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
33 #include "wine/debug.h"
34 #include "wine/unicode.h"
36 #include "mshtml_private.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
40 static const WCHAR brW
[] = {'b','r',0};
41 static const WCHAR hrW
[] = {'h','r',0};
44 const IHTMLTxtRangeVtbl
*lpHTMLTxtRangeVtbl
;
45 const IOleCommandTargetVtbl
*lpOleCommandTargetVtbl
;
55 #define HTMLTXTRANGE(x) ((IHTMLTxtRange*) &(x)->lpHTMLTxtRangeVtbl)
79 static HTMLTxtRange
*get_range_object(HTMLDocument
*doc
, IHTMLTxtRange
*iface
)
83 LIST_FOR_EACH_ENTRY(iter
, &doc
->range_list
, HTMLTxtRange
, entry
) {
84 if(HTMLTXTRANGE(iter
) == iface
)
88 ERR("Could not find range in document\n");
92 static range_unit_t
string_to_unit(LPCWSTR str
)
94 static const WCHAR characterW
[] =
95 {'c','h','a','r','a','c','t','e','r',0};
96 static const WCHAR wordW
[] =
98 static const WCHAR sentenceW
[] =
99 {'s','e','n','t','e','n','c','e',0};
100 static const WCHAR texteditW
[] =
101 {'t','e','x','t','e','d','i','t',0};
103 if(!strcmpiW(str
, characterW
)) return RU_CHAR
;
104 if(!strcmpiW(str
, wordW
)) return RU_WORD
;
105 if(!strcmpiW(str
, sentenceW
)) return RU_SENTENCE
;
106 if(!strcmpiW(str
, texteditW
)) return RU_TEXTEDIT
;
111 static int string_to_nscmptype(LPCWSTR str
)
113 static const WCHAR seW
[] = {'S','t','a','r','t','T','o','E','n','d',0};
114 static const WCHAR ssW
[] = {'S','t','a','r','t','T','o','S','t','a','r','t',0};
115 static const WCHAR esW
[] = {'E','n','d','T','o','S','t','a','r','t',0};
116 static const WCHAR eeW
[] = {'E','n','d','T','o','E','n','d',0};
118 if(!strcmpiW(str
, seW
)) return NS_START_TO_END
;
119 if(!strcmpiW(str
, ssW
)) return NS_START_TO_START
;
120 if(!strcmpiW(str
, esW
)) return NS_END_TO_START
;
121 if(!strcmpiW(str
, eeW
)) return NS_END_TO_END
;
126 static PRUint16
get_node_type(nsIDOMNode
*node
)
131 nsIDOMNode_GetNodeType(node
, &type
);
136 static BOOL
is_elem_tag(nsIDOMNode
*node
, LPCWSTR istag
)
140 const PRUnichar
*tag
;
144 nsres
= nsIDOMNode_QueryInterface(node
, &IID_nsIDOMElement
, (void**)&elem
);
148 nsAString_Init(&tag_str
, NULL
);
149 nsIDOMElement_GetTagName(elem
, &tag_str
);
150 nsIDOMElement_Release(elem
);
151 nsAString_GetData(&tag_str
, &tag
);
153 ret
= !strcmpiW(tag
, istag
);
155 nsAString_Finish(&tag_str
);
160 static BOOL
is_space_elem(nsIDOMNode
*node
)
164 const PRUnichar
*tag
;
168 nsres
= nsIDOMNode_QueryInterface(node
, &IID_nsIDOMElement
, (void**)&elem
);
172 nsAString_Init(&tag_str
, NULL
);
173 nsIDOMElement_GetTagName(elem
, &tag_str
);
174 nsIDOMElement_Release(elem
);
175 nsAString_GetData(&tag_str
, &tag
);
177 ret
= !strcmpiW(tag
, brW
) || !strcmpiW(tag
, hrW
);
179 nsAString_Finish(&tag_str
);
184 static inline void wstrbuf_init(wstrbuf_t
*buf
)
188 buf
->buf
= heap_alloc(buf
->size
* sizeof(WCHAR
));
192 static inline void wstrbuf_finish(wstrbuf_t
*buf
)
197 static void wstrbuf_append_len(wstrbuf_t
*buf
, LPCWSTR str
, int len
)
199 if(buf
->len
+len
>= buf
->size
) {
200 buf
->size
= 2*buf
->len
+len
;
201 buf
->buf
= heap_realloc(buf
->buf
, buf
->size
* sizeof(WCHAR
));
204 memcpy(buf
->buf
+buf
->len
, str
, len
*sizeof(WCHAR
));
206 buf
->buf
[buf
->len
] = 0;
209 static inline void wstrbuf_append(wstrbuf_t
*buf
, LPCWSTR str
)
211 wstrbuf_append_len(buf
, str
, strlenW(str
));
214 static void wstrbuf_append_nodetxt(wstrbuf_t
*buf
, LPCWSTR str
, int len
)
216 const WCHAR
*s
= str
;
219 TRACE("%s\n", debugstr_wn(str
, len
));
221 if(buf
->len
+len
>= buf
->size
) {
222 buf
->size
= 2*buf
->len
+len
;
223 buf
->buf
= heap_realloc(buf
->buf
, buf
->size
* sizeof(WCHAR
));
226 if(buf
->len
&& isspaceW(buf
->buf
[buf
->len
-1])) {
227 while(s
< str
+len
&& isspaceW(*s
))
231 d
= buf
->buf
+buf
->len
;
236 while(s
< str
+len
&& isspaceW(*s
))
243 buf
->len
= d
- buf
->buf
;
247 static void wstrbuf_append_node(wstrbuf_t
*buf
, nsIDOMNode
*node
)
250 switch(get_node_type(node
)) {
254 const PRUnichar
*data
;
256 nsIDOMNode_QueryInterface(node
, &IID_nsIDOMText
, (void**)&nstext
);
258 nsAString_Init(&data_str
, NULL
);
259 nsIDOMText_GetData(nstext
, &data_str
);
260 nsAString_GetData(&data_str
, &data
);
261 wstrbuf_append_nodetxt(buf
, data
, strlenW(data
));
262 nsAString_Finish(&data_str
);
264 nsIDOMText_Release(nstext
);
269 if(is_elem_tag(node
, brW
)) {
270 static const WCHAR endlW
[] = {'\r','\n'};
271 wstrbuf_append_len(buf
, endlW
, 2);
272 }else if(is_elem_tag(node
, hrW
)) {
273 static const WCHAR endl2W
[] = {'\r','\n','\r','\n'};
274 wstrbuf_append_len(buf
, endl2W
, 4);
279 static BOOL
fill_nodestr(dompos_t
*pos
)
284 if(pos
->type
!= TEXT_NODE
)
287 nsres
= nsIDOMNode_QueryInterface(pos
->node
, &IID_nsIDOMText
, (void**)&text
);
291 nsAString_Init(&pos
->str
, NULL
);
292 nsIDOMText_GetData(text
, &pos
->str
);
293 nsIDOMText_Release(text
);
294 nsAString_GetData(&pos
->str
, &pos
->p
);
297 pos
->off
= *pos
->p
? strlenW(pos
->p
)-1 : 0;
302 static nsIDOMNode
*next_node(nsIDOMNode
*iter
)
304 nsIDOMNode
*ret
, *tmp
;
310 nsres
= nsIDOMNode_GetFirstChild(iter
, &ret
);
311 if(NS_SUCCEEDED(nsres
) && ret
)
314 nsIDOMNode_AddRef(iter
);
317 nsres
= nsIDOMNode_GetNextSibling(iter
, &ret
);
318 if(NS_SUCCEEDED(nsres
) && ret
) {
319 nsIDOMNode_Release(iter
);
323 nsres
= nsIDOMNode_GetParentNode(iter
, &tmp
);
324 nsIDOMNode_Release(iter
);
326 }while(NS_SUCCEEDED(nsres
) && iter
);
331 static nsIDOMNode
*prev_node(HTMLTxtRange
*This
, nsIDOMNode
*iter
)
333 nsIDOMNode
*ret
, *tmp
;
337 nsIDOMHTMLDocument
*nshtmldoc
;
338 nsIDOMHTMLElement
*nselem
;
339 nsIDOMDocument
*nsdoc
;
341 nsIWebNavigation_GetDocument(This
->doc
->nscontainer
->navigation
, &nsdoc
);
342 nsIDOMDocument_QueryInterface(nsdoc
, &IID_nsIDOMHTMLDocument
, (void**)&nshtmldoc
);
343 nsIDOMDocument_Release(nsdoc
);
344 nsIDOMHTMLDocument_GetBody(nshtmldoc
, &nselem
);
345 nsIDOMHTMLDocument_Release(nshtmldoc
);
347 nsIDOMElement_GetLastChild(nselem
, &tmp
);
349 return (nsIDOMNode
*)nselem
;
353 nsIDOMNode_GetLastChild(ret
, &tmp
);
356 nsIDOMElement_Release(nselem
);
361 nsres
= nsIDOMNode_GetLastChild(iter
, &ret
);
362 if(NS_SUCCEEDED(nsres
) && ret
)
365 nsIDOMNode_AddRef(iter
);
368 nsres
= nsIDOMNode_GetPreviousSibling(iter
, &ret
);
369 if(NS_SUCCEEDED(nsres
) && ret
) {
370 nsIDOMNode_Release(iter
);
374 nsres
= nsIDOMNode_GetParentNode(iter
, &tmp
);
375 nsIDOMNode_Release(iter
);
377 }while(NS_SUCCEEDED(nsres
) && iter
);
382 static nsIDOMNode
*get_child_node(nsIDOMNode
*node
, PRUint32 off
)
384 nsIDOMNodeList
*node_list
;
385 nsIDOMNode
*ret
= NULL
;
387 nsIDOMNode_GetChildNodes(node
, &node_list
);
388 nsIDOMNodeList_Item(node_list
, off
, &ret
);
389 nsIDOMNodeList_Release(node_list
);
394 static void get_cur_pos(HTMLTxtRange
*This
, BOOL start
, dompos_t
*pos
)
403 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
408 nsIDOMRange_GetStartContainer(This
->nsrange
, &node
);
409 nsIDOMRange_GetStartOffset(This
->nsrange
, &off
);
411 nsIDOMRange_GetEndContainer(This
->nsrange
, &node
);
412 nsIDOMRange_GetEndOffset(This
->nsrange
, &off
);
415 pos
->type
= get_node_type(node
);
416 if(pos
->type
== ELEMENT_NODE
) {
418 pos
->node
= get_child_node(node
, off
);
421 pos
->node
= off
? get_child_node(node
, off
-1) : prev_node(This
, node
);
425 pos
->type
= get_node_type(pos
->node
);
426 nsIDOMNode_Release(node
);
434 pos
->node
= prev_node(This
, node
);
436 nsIDOMNode_Release(node
);
439 if(pos
->type
== TEXT_NODE
)
443 static void set_range_pos(HTMLTxtRange
*This
, BOOL start
, dompos_t
*pos
)
448 if(pos
->type
== TEXT_NODE
)
449 nsres
= nsIDOMRange_SetStart(This
->nsrange
, pos
->node
, pos
->off
);
451 nsres
= nsIDOMRange_SetStartBefore(This
->nsrange
, pos
->node
);
453 if(pos
->type
== TEXT_NODE
&& pos
->p
[pos
->off
+1])
454 nsres
= nsIDOMRange_SetEnd(This
->nsrange
, pos
->node
, pos
->off
+1);
456 nsres
= nsIDOMRange_SetEndAfter(This
->nsrange
, pos
->node
);
460 ERR("failed: %p %08x\n", pos
->node
, nsres
);
463 static inline void dompos_release(dompos_t
*pos
)
466 nsIDOMNode_Release(pos
->node
);
469 nsAString_Finish(&pos
->str
);
472 static inline void dompos_addref(dompos_t
*pos
)
475 nsIDOMNode_AddRef(pos
->node
);
477 if(pos
->type
== TEXT_NODE
)
481 static inline BOOL
dompos_cmp(const dompos_t
*pos1
, const dompos_t
*pos2
)
483 return pos1
->node
== pos2
->node
&& pos1
->off
== pos2
->off
;
486 static void range_to_string(HTMLTxtRange
*This
, wstrbuf_t
*buf
)
488 nsIDOMNode
*iter
, *tmp
;
489 dompos_t start_pos
, end_pos
;
492 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
500 get_cur_pos(This
, FALSE
, &end_pos
);
501 get_cur_pos(This
, TRUE
, &start_pos
);
503 if(start_pos
.type
== TEXT_NODE
) {
504 if(start_pos
.node
== end_pos
.node
) {
505 wstrbuf_append_nodetxt(buf
, start_pos
.p
+start_pos
.off
, end_pos
.off
-start_pos
.off
+1);
506 iter
= start_pos
.node
;
507 nsIDOMNode_AddRef(iter
);
509 wstrbuf_append_nodetxt(buf
, start_pos
.p
+start_pos
.off
, strlenW(start_pos
.p
+start_pos
.off
));
510 iter
= next_node(start_pos
.node
);
513 iter
= start_pos
.node
;
514 nsIDOMNode_AddRef(iter
);
517 while(iter
!= end_pos
.node
) {
518 wstrbuf_append_node(buf
, iter
);
519 tmp
= next_node(iter
);
520 nsIDOMNode_Release(iter
);
524 nsIDOMNode_AddRef(end_pos
.node
);
526 if(start_pos
.node
!= end_pos
.node
) {
527 if(end_pos
.type
== TEXT_NODE
)
528 wstrbuf_append_nodetxt(buf
, end_pos
.p
, end_pos
.off
+1);
530 wstrbuf_append_node(buf
, end_pos
.node
);
533 nsIDOMNode_Release(iter
);
534 dompos_release(&start_pos
);
535 dompos_release(&end_pos
);
540 for(p
= buf
->buf
+buf
->len
-1; p
>= buf
->buf
&& isspaceW(*p
); p
--);
542 p
= strchrW(p
, '\r');
548 static WCHAR
get_pos_char(const dompos_t
*pos
)
552 return pos
->p
[pos
->off
];
554 if(is_space_elem(pos
->node
))
561 static void end_space(const dompos_t
*pos
, dompos_t
*new_pos
)
566 dompos_addref(new_pos
);
568 if(pos
->type
!= TEXT_NODE
)
571 p
= new_pos
->p
+new_pos
->off
;
573 if(!*p
|| !isspace(*p
))
576 while(p
[1] && isspace(p
[1]))
579 new_pos
->off
= p
- new_pos
->p
;
582 static WCHAR
next_char(const dompos_t
*pos
, dompos_t
*new_pos
)
584 nsIDOMNode
*iter
, *tmp
;
585 dompos_t last_space
, tmp_pos
;
589 if(pos
->type
== TEXT_NODE
&& pos
->off
!= -1 && pos
->p
[pos
->off
]) {
593 while(isspaceW(*++p
));
597 if(*p
&& isspaceW(*p
)) {
599 while(p
[1] && isspaceW(p
[1]))
605 new_pos
->off
= p
- pos
->p
;
606 dompos_addref(new_pos
);
608 return cspace
? cspace
: *p
;
611 last_space
.off
= p
- pos
->p
;
612 dompos_addref(&last_space
);
616 iter
= next_node(pos
->node
);
619 switch(get_node_type(iter
)) {
622 tmp_pos
.type
= TEXT_NODE
;
623 dompos_addref(&tmp_pos
);
628 dompos_release(&tmp_pos
);
630 }else if(isspaceW(*p
)) {
632 dompos_release(&last_space
);
636 while(p
[1] && isspaceW(p
[1]))
639 tmp_pos
.off
= p
-tmp_pos
.p
;
642 last_space
= tmp_pos
;
647 nsIDOMNode_Release(iter
);
650 *new_pos
= last_space
;
651 dompos_release(&tmp_pos
);
652 nsIDOMNode_Release(iter
);
660 nsIDOMNode_Release(iter
);
664 if(!is_space_elem(iter
))
668 dompos_release(&last_space
);
671 nsIDOMNode_AddRef(iter
);
672 last_space
.node
= iter
;
673 last_space
.type
= ELEMENT_NODE
;
679 iter
= next_node(iter
);
680 nsIDOMNode_Release(tmp
);
684 *new_pos
= last_space
;
687 dompos_addref(new_pos
);
693 static WCHAR
prev_char(HTMLTxtRange
*This
, const dompos_t
*pos
, dompos_t
*new_pos
)
695 nsIDOMNode
*iter
, *tmp
;
697 BOOL skip_space
= FALSE
;
699 if(pos
->type
== TEXT_NODE
&& isspaceW(pos
->p
[pos
->off
]))
702 if(pos
->type
== TEXT_NODE
&& pos
->off
) {
703 p
= pos
->p
+pos
->off
-1;
706 while(p
>= pos
->p
&& isspace(*p
))
712 new_pos
->off
= p
-pos
->p
;
713 dompos_addref(new_pos
);
714 return new_pos
->p
[new_pos
->off
];
718 iter
= prev_node(This
, pos
->node
);
721 switch(get_node_type(iter
)) {
726 tmp_pos
.type
= TEXT_NODE
;
727 dompos_addref(&tmp_pos
);
729 p
= tmp_pos
.p
+ strlenW(tmp_pos
.p
)-1;
732 while(p
>= tmp_pos
.p
&& isspaceW(*p
))
737 dompos_release(&tmp_pos
);
741 tmp_pos
.off
= p
-tmp_pos
.p
;
743 nsIDOMNode_Release(iter
);
748 if(!is_space_elem(iter
))
756 new_pos
->node
= iter
;
757 new_pos
->type
= ELEMENT_NODE
;
764 iter
= prev_node(This
, iter
);
765 nsIDOMNode_Release(tmp
);
769 dompos_addref(new_pos
);
773 static long move_next_chars(long cnt
, const dompos_t
*pos
, BOOL col
, const dompos_t
*bound_pos
,
774 BOOL
*bounded
, dompos_t
*new_pos
)
787 end_space(pos
, new_pos
);
791 c
= next_char(pos
, &iter
);
796 c
= next_char(&tmp
, &iter
);
797 dompos_release(&tmp
);
802 if(bound_pos
&& dompos_cmp(&tmp
, bound_pos
)) {
812 static long move_prev_chars(HTMLTxtRange
*This
, long cnt
, const dompos_t
*pos
, BOOL end
,
813 const dompos_t
*bound_pos
, BOOL
*bounded
, dompos_t
*new_pos
)
822 c
= prev_char(This
, pos
, &iter
);
826 while(c
&& ret
< cnt
) {
828 c
= prev_char(This
, &tmp
, &iter
);
829 dompos_release(&tmp
);
838 if(bound_pos
&& dompos_cmp(&iter
, bound_pos
)) {
845 return bounded
&& *bounded
? ret
+1 : ret
;
848 static long find_prev_space(HTMLTxtRange
*This
, const dompos_t
*pos
, BOOL first_space
, dompos_t
*ret
)
853 c
= prev_char(This
, pos
, &iter
);
854 if(!c
|| (first_space
&& isspaceW(c
))) {
861 c
= prev_char(This
, &tmp
, &iter
);
862 if(!c
|| isspaceW(c
)) {
863 dompos_release(&iter
);
866 dompos_release(&tmp
);
873 static int find_word_end(const dompos_t
*pos
, dompos_t
*ret
)
878 c
= get_pos_char(pos
);
885 c
= next_char(pos
, &iter
);
896 while(c
&& !isspaceW(c
)) {
898 c
= next_char(&tmp
, &iter
);
900 dompos_release(&iter
);
904 dompos_release(&tmp
);
912 static long move_next_words(long cnt
, const dompos_t
*pos
, dompos_t
*new_pos
)
918 c
= get_pos_char(pos
);
920 end_space(pos
, &iter
);
923 c
= next_char(pos
, &iter
);
928 while(c
&& ret
< cnt
) {
930 c
= next_char(&tmp
, &iter
);
931 dompos_release(&tmp
);
940 static long move_prev_words(HTMLTxtRange
*This
, long cnt
, const dompos_t
*pos
, dompos_t
*new_pos
)
946 dompos_addref(&iter
);
949 if(!find_prev_space(This
, &iter
, FALSE
, &tmp
))
952 dompos_release(&iter
);
961 #define HTMLTXTRANGE_THIS(iface) DEFINE_THIS(HTMLTxtRange, HTMLTxtRange, iface)
963 static HRESULT WINAPI
HTMLTxtRange_QueryInterface(IHTMLTxtRange
*iface
, REFIID riid
, void **ppv
)
965 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
969 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
970 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
971 *ppv
= HTMLTXTRANGE(This
);
972 }else if(IsEqualGUID(&IID_IDispatch
, riid
)) {
973 TRACE("(%p)->(IID_IDispatch %p)\n", This
, ppv
);
974 *ppv
= HTMLTXTRANGE(This
);
975 }else if(IsEqualGUID(&IID_IHTMLTxtRange
, riid
)) {
976 TRACE("(%p)->(IID_IHTMLTxtRange %p)\n", This
, ppv
);
977 *ppv
= HTMLTXTRANGE(This
);
978 }else if(IsEqualGUID(&IID_IOleCommandTarget
, riid
)) {
979 TRACE("(%p)->(IID_IOleCommandTarget %p)\n", This
, ppv
);
980 *ppv
= CMDTARGET(This
);
984 IUnknown_AddRef((IUnknown
*)*ppv
);
988 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
989 return E_NOINTERFACE
;
992 static ULONG WINAPI
HTMLTxtRange_AddRef(IHTMLTxtRange
*iface
)
994 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
995 LONG ref
= InterlockedIncrement(&This
->ref
);
997 TRACE("(%p) ref=%d\n", This
, ref
);
1002 static ULONG WINAPI
HTMLTxtRange_Release(IHTMLTxtRange
*iface
)
1004 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1005 LONG ref
= InterlockedDecrement(&This
->ref
);
1007 TRACE("(%p) ref=%d\n", This
, ref
);
1011 nsISelection_Release(This
->nsrange
);
1013 list_remove(&This
->entry
);
1020 static HRESULT WINAPI
HTMLTxtRange_GetTypeInfoCount(IHTMLTxtRange
*iface
, UINT
*pctinfo
)
1022 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1023 FIXME("(%p)->(%p)\n", This
, pctinfo
);
1027 static HRESULT WINAPI
HTMLTxtRange_GetTypeInfo(IHTMLTxtRange
*iface
, UINT iTInfo
,
1028 LCID lcid
, ITypeInfo
**ppTInfo
)
1030 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1031 FIXME("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
1035 static HRESULT WINAPI
HTMLTxtRange_GetIDsOfNames(IHTMLTxtRange
*iface
, REFIID riid
,
1036 LPOLESTR
*rgszNames
, UINT cNames
,
1037 LCID lcid
, DISPID
*rgDispId
)
1039 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1040 FIXME("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
1045 static HRESULT WINAPI
HTMLTxtRange_Invoke(IHTMLTxtRange
*iface
, DISPID dispIdMember
,
1046 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
1047 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
1049 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1050 FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
1051 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
1055 static HRESULT WINAPI
HTMLTxtRange_get_htmlText(IHTMLTxtRange
*iface
, BSTR
*p
)
1057 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1059 TRACE("(%p)->(%p)\n", This
, p
);
1064 nsIDOMDocumentFragment
*fragment
;
1067 nsres
= nsIDOMRange_CloneContents(This
->nsrange
, &fragment
);
1068 if(NS_SUCCEEDED(nsres
)) {
1069 const PRUnichar
*nstext
;
1072 nsAString_Init(&nsstr
, NULL
);
1073 nsnode_to_nsstring((nsIDOMNode
*)fragment
, &nsstr
);
1074 nsIDOMDocumentFragment_Release(fragment
);
1076 nsAString_GetData(&nsstr
, &nstext
);
1077 *p
= SysAllocString(nstext
);
1079 nsAString_Finish(&nsstr
);
1084 const WCHAR emptyW
[] = {0};
1085 *p
= SysAllocString(emptyW
);
1088 TRACE("return %s\n", debugstr_w(*p
));
1092 static HRESULT WINAPI
HTMLTxtRange_put_text(IHTMLTxtRange
*iface
, BSTR v
)
1094 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1095 nsIDOMDocument
*nsdoc
;
1096 nsIDOMText
*text_node
;
1100 TRACE("(%p)->(%s)\n", This
, debugstr_w(v
));
1103 return MSHTML_E_NODOC
;
1105 nsres
= nsIWebNavigation_GetDocument(This
->doc
->nscontainer
->navigation
, &nsdoc
);
1106 if(NS_FAILED(nsres
)) {
1107 ERR("GetDocument failed: %08x\n", nsres
);
1111 nsAString_Init(&text_str
, v
);
1112 nsres
= nsIDOMDocument_CreateTextNode(nsdoc
, &text_str
, &text_node
);
1113 nsIDOMDocument_Release(nsdoc
);
1114 nsAString_Finish(&text_str
);
1115 if(NS_FAILED(nsres
)) {
1116 ERR("CreateTextNode failed: %08x\n", nsres
);
1119 nsres
= nsIDOMRange_DeleteContents(This
->nsrange
);
1120 if(NS_FAILED(nsres
))
1121 ERR("DeleteContents failed: %08x\n", nsres
);
1123 nsres
= nsIDOMRange_InsertNode(This
->nsrange
, (nsIDOMNode
*)text_node
);
1124 if(NS_FAILED(nsres
))
1125 ERR("InsertNode failed: %08x\n", nsres
);
1127 nsres
= nsIDOMRange_SetEndAfter(This
->nsrange
, (nsIDOMNode
*)text_node
);
1128 if(NS_FAILED(nsres
))
1129 ERR("SetEndAfter failed: %08x\n", nsres
);
1131 return IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), VARIANT_FALSE
);
1134 static HRESULT WINAPI
HTMLTxtRange_get_text(IHTMLTxtRange
*iface
, BSTR
*p
)
1136 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1139 TRACE("(%p)->(%p)\n", This
, p
);
1146 range_to_string(This
, &buf
);
1148 *p
= SysAllocString(buf
.buf
);
1149 wstrbuf_finish(&buf
);
1151 TRACE("ret %s\n", debugstr_w(*p
));
1155 static HRESULT WINAPI
HTMLTxtRange_parentElement(IHTMLTxtRange
*iface
, IHTMLElement
**parent
)
1157 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1158 nsIDOMNode
*nsnode
, *tmp
;
1161 TRACE("(%p)->(%p)\n", This
, parent
);
1163 nsIDOMRange_GetCommonAncestorContainer(This
->nsrange
, &nsnode
);
1164 while(nsnode
&& get_node_type(nsnode
) != ELEMENT_NODE
) {
1165 nsIDOMNode_GetParentNode(nsnode
, &tmp
);
1166 nsIDOMNode_Release(nsnode
);
1175 node
= get_node(This
->doc
, nsnode
);
1176 nsIDOMNode_Release(nsnode
);
1178 return IHTMLDOMNode_QueryInterface(HTMLDOMNODE(node
), &IID_IHTMLElement
, (void**)parent
);
1181 static HRESULT WINAPI
HTMLTxtRange_duplicate(IHTMLTxtRange
*iface
, IHTMLTxtRange
**Duplicate
)
1183 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1184 nsIDOMRange
*nsrange
= NULL
;
1186 TRACE("(%p)->(%p)\n", This
, Duplicate
);
1188 nsIDOMRange_CloneRange(This
->nsrange
, &nsrange
);
1189 *Duplicate
= HTMLTxtRange_Create(This
->doc
, nsrange
);
1190 nsIDOMRange_Release(nsrange
);
1195 static HRESULT WINAPI
HTMLTxtRange_inRange(IHTMLTxtRange
*iface
, IHTMLTxtRange
*Range
,
1196 VARIANT_BOOL
*InRange
)
1198 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1199 HTMLTxtRange
*src_range
;
1203 TRACE("(%p)->(%p %p)\n", This
, Range
, InRange
);
1205 *InRange
= VARIANT_FALSE
;
1207 src_range
= get_range_object(This
->doc
, Range
);
1211 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, NS_START_TO_START
,
1212 src_range
->nsrange
, &nsret
);
1213 if(NS_SUCCEEDED(nsres
) && nsret
<= 0) {
1214 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, NS_END_TO_END
,
1215 src_range
->nsrange
, &nsret
);
1216 if(NS_SUCCEEDED(nsres
) && nsret
>= 0)
1217 *InRange
= VARIANT_TRUE
;
1220 if(NS_FAILED(nsres
))
1221 ERR("CompareBoundaryPoints failed: %08x\n", nsres
);
1226 static HRESULT WINAPI
HTMLTxtRange_isEqual(IHTMLTxtRange
*iface
, IHTMLTxtRange
*Range
,
1227 VARIANT_BOOL
*IsEqual
)
1229 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1230 HTMLTxtRange
*src_range
;
1234 TRACE("(%p)->(%p %p)\n", This
, Range
, IsEqual
);
1236 *IsEqual
= VARIANT_FALSE
;
1238 src_range
= get_range_object(This
->doc
, Range
);
1242 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, NS_START_TO_START
,
1243 src_range
->nsrange
, &nsret
);
1244 if(NS_SUCCEEDED(nsres
) && !nsret
) {
1245 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, NS_END_TO_END
,
1246 src_range
->nsrange
, &nsret
);
1247 if(NS_SUCCEEDED(nsres
) && !nsret
)
1248 *IsEqual
= VARIANT_TRUE
;
1251 if(NS_FAILED(nsres
))
1252 ERR("CompareBoundaryPoints failed: %08x\n", nsres
);
1257 static HRESULT WINAPI
HTMLTxtRange_scrollIntoView(IHTMLTxtRange
*iface
, VARIANT_BOOL fStart
)
1259 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1260 FIXME("(%p)->(%x)\n", This
, fStart
);
1264 static HRESULT WINAPI
HTMLTxtRange_collapse(IHTMLTxtRange
*iface
, VARIANT_BOOL Start
)
1266 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1268 TRACE("(%p)->(%x)\n", This
, Start
);
1270 nsIDOMRange_Collapse(This
->nsrange
, Start
!= VARIANT_FALSE
);
1274 static HRESULT WINAPI
HTMLTxtRange_expand(IHTMLTxtRange
*iface
, BSTR Unit
, VARIANT_BOOL
*Success
)
1276 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1279 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(Unit
), Success
);
1281 unit
= string_to_unit(Unit
);
1282 if(unit
== RU_UNKNOWN
)
1283 return E_INVALIDARG
;
1285 *Success
= VARIANT_FALSE
;
1289 dompos_t end_pos
, start_pos
, new_start_pos
, new_end_pos
;
1292 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
1294 get_cur_pos(This
, TRUE
, &start_pos
);
1295 get_cur_pos(This
, FALSE
, &end_pos
);
1297 if(find_word_end(&end_pos
, &new_end_pos
) || collapsed
) {
1298 set_range_pos(This
, FALSE
, &new_end_pos
);
1299 *Success
= VARIANT_TRUE
;
1302 if(start_pos
.type
&& (get_pos_char(&end_pos
) || !dompos_cmp(&new_end_pos
, &end_pos
))) {
1303 if(find_prev_space(This
, &start_pos
, TRUE
, &new_start_pos
)) {
1304 set_range_pos(This
, TRUE
, &new_start_pos
);
1305 *Success
= VARIANT_TRUE
;
1307 dompos_release(&new_start_pos
);
1310 dompos_release(&new_end_pos
);
1311 dompos_release(&end_pos
);
1312 dompos_release(&start_pos
);
1318 nsIDOMDocument
*nsdoc
;
1319 nsIDOMHTMLDocument
*nshtmldoc
;
1320 nsIDOMHTMLElement
*nsbody
= NULL
;
1323 nsres
= nsIWebNavigation_GetDocument(This
->doc
->nscontainer
->navigation
, &nsdoc
);
1324 if(NS_FAILED(nsres
) || !nsdoc
) {
1325 ERR("GetDocument failed: %08x\n", nsres
);
1329 nsIDOMDocument_QueryInterface(nsdoc
, &IID_nsIDOMHTMLDocument
, (void**)&nshtmldoc
);
1330 nsIDOMDocument_Release(nsdoc
);
1332 nsres
= nsIDOMHTMLDocument_GetBody(nshtmldoc
, &nsbody
);
1333 nsIDOMHTMLDocument_Release(nshtmldoc
);
1334 if(NS_FAILED(nsres
) || !nsbody
) {
1335 ERR("Could not get body: %08x\n", nsres
);
1339 nsres
= nsIDOMRange_SelectNodeContents(This
->nsrange
, (nsIDOMNode
*)nsbody
);
1340 nsIDOMHTMLElement_Release(nsbody
);
1341 if(NS_FAILED(nsres
)) {
1342 ERR("Collapse failed: %08x\n", nsres
);
1346 *Success
= VARIANT_TRUE
;
1351 FIXME("Unimplemented unit %s\n", debugstr_w(Unit
));
1357 static HRESULT WINAPI
HTMLTxtRange_move(IHTMLTxtRange
*iface
, BSTR Unit
,
1358 long Count
, long *ActualCount
)
1360 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1363 TRACE("(%p)->(%s %ld %p)\n", This
, debugstr_w(Unit
), Count
, ActualCount
);
1365 unit
= string_to_unit(Unit
);
1366 if(unit
== RU_UNKNOWN
)
1367 return E_INVALIDARG
;
1371 return IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), TRUE
);
1376 dompos_t cur_pos
, new_pos
;
1378 get_cur_pos(This
, TRUE
, &cur_pos
);
1381 *ActualCount
= move_next_chars(Count
, &cur_pos
, TRUE
, NULL
, NULL
, &new_pos
);
1382 set_range_pos(This
, FALSE
, &new_pos
);
1383 dompos_release(&new_pos
);
1385 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), FALSE
);
1387 *ActualCount
= -move_prev_chars(This
, -Count
, &cur_pos
, FALSE
, NULL
, NULL
, &new_pos
);
1388 set_range_pos(This
, TRUE
, &new_pos
);
1389 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), TRUE
);
1390 dompos_release(&new_pos
);
1393 dompos_release(&cur_pos
);
1398 dompos_t cur_pos
, new_pos
;
1400 get_cur_pos(This
, TRUE
, &cur_pos
);
1403 *ActualCount
= move_next_words(Count
, &cur_pos
, &new_pos
);
1404 set_range_pos(This
, FALSE
, &new_pos
);
1405 dompos_release(&new_pos
);
1406 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), FALSE
);
1408 *ActualCount
= -move_prev_words(This
, -Count
, &cur_pos
, &new_pos
);
1409 set_range_pos(This
, TRUE
, &new_pos
);
1410 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), TRUE
);
1411 dompos_release(&new_pos
);
1414 dompos_release(&cur_pos
);
1419 FIXME("unimplemented unit %s\n", debugstr_w(Unit
));
1422 TRACE("ret %ld\n", *ActualCount
);
1426 static HRESULT WINAPI
HTMLTxtRange_moveStart(IHTMLTxtRange
*iface
, BSTR Unit
,
1427 long Count
, long *ActualCount
)
1429 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1432 TRACE("(%p)->(%s %ld %p)\n", This
, debugstr_w(Unit
), Count
, ActualCount
);
1434 unit
= string_to_unit(Unit
);
1435 if(unit
== RU_UNKNOWN
)
1436 return E_INVALIDARG
;
1445 dompos_t start_pos
, end_pos
, new_pos
;
1448 get_cur_pos(This
, TRUE
, &start_pos
);
1449 get_cur_pos(This
, FALSE
, &end_pos
);
1450 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
1455 *ActualCount
= move_next_chars(Count
, &start_pos
, collapsed
, &end_pos
, &bounded
, &new_pos
);
1456 set_range_pos(This
, !bounded
, &new_pos
);
1458 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), FALSE
);
1460 *ActualCount
= -move_prev_chars(This
, -Count
, &start_pos
, FALSE
, NULL
, NULL
, &new_pos
);
1461 set_range_pos(This
, TRUE
, &new_pos
);
1464 dompos_release(&start_pos
);
1465 dompos_release(&end_pos
);
1466 dompos_release(&new_pos
);
1471 FIXME("unimplemented unit %s\n", debugstr_w(Unit
));
1477 static HRESULT WINAPI
HTMLTxtRange_moveEnd(IHTMLTxtRange
*iface
, BSTR Unit
,
1478 long Count
, long *ActualCount
)
1480 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1483 TRACE("(%p)->(%s %ld %p)\n", This
, debugstr_w(Unit
), Count
, ActualCount
);
1485 unit
= string_to_unit(Unit
);
1486 if(unit
== RU_UNKNOWN
)
1487 return E_INVALIDARG
;
1496 dompos_t start_pos
, end_pos
, new_pos
;
1499 get_cur_pos(This
, TRUE
, &start_pos
);
1500 get_cur_pos(This
, FALSE
, &end_pos
);
1501 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
1504 *ActualCount
= move_next_chars(Count
, &end_pos
, collapsed
, NULL
, NULL
, &new_pos
);
1505 set_range_pos(This
, FALSE
, &new_pos
);
1509 *ActualCount
= -move_prev_chars(This
, -Count
, &end_pos
, TRUE
, &start_pos
, &bounded
, &new_pos
);
1510 set_range_pos(This
, bounded
, &new_pos
);
1512 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), TRUE
);
1515 dompos_release(&start_pos
);
1516 dompos_release(&end_pos
);
1517 dompos_release(&new_pos
);
1522 FIXME("unimplemented unit %s\n", debugstr_w(Unit
));
1528 static HRESULT WINAPI
HTMLTxtRange_select(IHTMLTxtRange
*iface
)
1530 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1532 TRACE("(%p)\n", This
);
1534 if(This
->doc
->nscontainer
) {
1535 nsIDOMWindow
*dom_window
= NULL
;
1536 nsISelection
*nsselection
;
1538 nsIWebBrowser_GetContentDOMWindow(This
->doc
->nscontainer
->webbrowser
, &dom_window
);
1539 nsIDOMWindow_GetSelection(dom_window
, &nsselection
);
1540 nsIDOMWindow_Release(dom_window
);
1542 nsISelection_RemoveAllRanges(nsselection
);
1543 nsISelection_AddRange(nsselection
, This
->nsrange
);
1545 nsISelection_Release(nsselection
);
1551 static HRESULT WINAPI
HTMLTxtRange_pasteHTML(IHTMLTxtRange
*iface
, BSTR html
)
1553 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1554 FIXME("(%p)->(%s)\n", This
, debugstr_w(html
));
1558 static HRESULT WINAPI
HTMLTxtRange_moveToElementText(IHTMLTxtRange
*iface
, IHTMLElement
*element
)
1560 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1561 FIXME("(%p)->(%p)\n", This
, element
);
1565 static HRESULT WINAPI
HTMLTxtRange_setEndPoint(IHTMLTxtRange
*iface
, BSTR how
,
1566 IHTMLTxtRange
*SourceRange
)
1568 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1569 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(how
), SourceRange
);
1573 static HRESULT WINAPI
HTMLTxtRange_compareEndPoints(IHTMLTxtRange
*iface
, BSTR how
,
1574 IHTMLTxtRange
*SourceRange
, long *ret
)
1576 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1577 HTMLTxtRange
*src_range
;
1582 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(how
), SourceRange
, ret
);
1584 nscmpt
= string_to_nscmptype(how
);
1586 return E_INVALIDARG
;
1588 src_range
= get_range_object(This
->doc
, SourceRange
);
1592 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, nscmpt
, src_range
->nsrange
, &nsret
);
1593 if(NS_FAILED(nsres
))
1594 ERR("CompareBoundaryPoints failed: %08x\n", nsres
);
1600 static HRESULT WINAPI
HTMLTxtRange_findText(IHTMLTxtRange
*iface
, BSTR String
,
1601 long count
, long Flags
, VARIANT_BOOL
*Success
)
1603 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1604 FIXME("(%p)->(%s %ld %08lx %p)\n", This
, debugstr_w(String
), count
, Flags
, Success
);
1608 static HRESULT WINAPI
HTMLTxtRange_moveToPoint(IHTMLTxtRange
*iface
, long x
, long y
)
1610 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1611 FIXME("(%p)->(%ld %ld)\n", This
, x
, y
);
1615 static HRESULT WINAPI
HTMLTxtRange_getBookmark(IHTMLTxtRange
*iface
, BSTR
*Bookmark
)
1617 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1618 FIXME("(%p)->(%p)\n", This
, Bookmark
);
1622 static HRESULT WINAPI
HTMLTxtRange_moveToBookmark(IHTMLTxtRange
*iface
, BSTR Bookmark
,
1623 VARIANT_BOOL
*Success
)
1625 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1626 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(Bookmark
), Success
);
1630 static HRESULT WINAPI
HTMLTxtRange_queryCommandSupported(IHTMLTxtRange
*iface
, BSTR cmdID
,
1631 VARIANT_BOOL
*pfRet
)
1633 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1634 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1638 static HRESULT WINAPI
HTMLTxtRange_queryCommandEnabled(IHTMLTxtRange
*iface
, BSTR cmdID
,
1639 VARIANT_BOOL
*pfRet
)
1641 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1642 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1646 static HRESULT WINAPI
HTMLTxtRange_queryCommandState(IHTMLTxtRange
*iface
, BSTR cmdID
,
1647 VARIANT_BOOL
*pfRet
)
1649 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1650 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1654 static HRESULT WINAPI
HTMLTxtRange_queryCommandIndeterm(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 static HRESULT WINAPI
HTMLTxtRange_queryCommandText(IHTMLTxtRange
*iface
, BSTR cmdID
,
1665 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1666 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pcmdText
);
1670 static HRESULT WINAPI
HTMLTxtRange_queryCommandValue(IHTMLTxtRange
*iface
, BSTR cmdID
,
1673 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1674 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pcmdValue
);
1678 static HRESULT WINAPI
HTMLTxtRange_execCommand(IHTMLTxtRange
*iface
, BSTR cmdID
,
1679 VARIANT_BOOL showUI
, VARIANT value
, VARIANT_BOOL
*pfRet
)
1681 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1682 FIXME("(%p)->(%s %x v %p)\n", This
, debugstr_w(cmdID
), showUI
, pfRet
);
1686 static HRESULT WINAPI
HTMLTxtRange_execCommandShowHelp(IHTMLTxtRange
*iface
, BSTR cmdID
,
1687 VARIANT_BOOL
*pfRet
)
1689 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1690 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1694 #undef HTMLTXTRANGE_THIS
1696 static const IHTMLTxtRangeVtbl HTMLTxtRangeVtbl
= {
1697 HTMLTxtRange_QueryInterface
,
1698 HTMLTxtRange_AddRef
,
1699 HTMLTxtRange_Release
,
1700 HTMLTxtRange_GetTypeInfoCount
,
1701 HTMLTxtRange_GetTypeInfo
,
1702 HTMLTxtRange_GetIDsOfNames
,
1703 HTMLTxtRange_Invoke
,
1704 HTMLTxtRange_get_htmlText
,
1705 HTMLTxtRange_put_text
,
1706 HTMLTxtRange_get_text
,
1707 HTMLTxtRange_parentElement
,
1708 HTMLTxtRange_duplicate
,
1709 HTMLTxtRange_inRange
,
1710 HTMLTxtRange_isEqual
,
1711 HTMLTxtRange_scrollIntoView
,
1712 HTMLTxtRange_collapse
,
1713 HTMLTxtRange_expand
,
1715 HTMLTxtRange_moveStart
,
1716 HTMLTxtRange_moveEnd
,
1717 HTMLTxtRange_select
,
1718 HTMLTxtRange_pasteHTML
,
1719 HTMLTxtRange_moveToElementText
,
1720 HTMLTxtRange_setEndPoint
,
1721 HTMLTxtRange_compareEndPoints
,
1722 HTMLTxtRange_findText
,
1723 HTMLTxtRange_moveToPoint
,
1724 HTMLTxtRange_getBookmark
,
1725 HTMLTxtRange_moveToBookmark
,
1726 HTMLTxtRange_queryCommandSupported
,
1727 HTMLTxtRange_queryCommandEnabled
,
1728 HTMLTxtRange_queryCommandState
,
1729 HTMLTxtRange_queryCommandIndeterm
,
1730 HTMLTxtRange_queryCommandText
,
1731 HTMLTxtRange_queryCommandValue
,
1732 HTMLTxtRange_execCommand
,
1733 HTMLTxtRange_execCommandShowHelp
1736 #define OLECMDTRG_THIS(iface) DEFINE_THIS(HTMLTxtRange, OleCommandTarget, iface)
1738 static HRESULT WINAPI
RangeCommandTarget_QueryInterface(IOleCommandTarget
*iface
, REFIID riid
, void **ppv
)
1740 HTMLTxtRange
*This
= OLECMDTRG_THIS(iface
);
1741 return IHTMLTxtRange_QueryInterface(HTMLTXTRANGE(This
), riid
, ppv
);
1744 static ULONG WINAPI
RangeCommandTarget_AddRef(IOleCommandTarget
*iface
)
1746 HTMLTxtRange
*This
= OLECMDTRG_THIS(iface
);
1747 return IHTMLTxtRange_AddRef(HTMLTXTRANGE(This
));
1750 static ULONG WINAPI
RangeCommandTarget_Release(IOleCommandTarget
*iface
)
1752 HTMLTxtRange
*This
= OLECMDTRG_THIS(iface
);
1753 return IHTMLTxtRange_Release(HTMLTXTRANGE(This
));
1756 static HRESULT WINAPI
RangeCommandTarget_QueryStatus(IOleCommandTarget
*iface
, const GUID
*pguidCmdGroup
,
1757 ULONG cCmds
, OLECMD prgCmds
[], OLECMDTEXT
*pCmdText
)
1759 HTMLTxtRange
*This
= OLECMDTRG_THIS(iface
);
1760 FIXME("(%p)->(%s %d %p %p)\n", This
, debugstr_guid(pguidCmdGroup
), cCmds
, prgCmds
, pCmdText
);
1764 static HRESULT
exec_indent(HTMLTxtRange
*This
, VARIANT
*in
, VARIANT
*out
)
1766 nsIDOMDocumentFragment
*fragment
;
1767 nsIDOMElement
*blockquote_elem
, *p_elem
;
1768 nsIDOMDocument
*nsdoc
;
1772 static const PRUnichar blockquoteW
[] = {'B','L','O','C','K','Q','U','O','T','E',0};
1773 static const PRUnichar pW
[] = {'P',0};
1775 TRACE("(%p)->(%p %p)\n", This
, in
, out
);
1777 nsIWebNavigation_GetDocument(This
->doc
->nscontainer
->navigation
, &nsdoc
);
1779 nsAString_Init(&tag_str
, blockquoteW
);
1780 nsIDOMDocument_CreateElement(nsdoc
, &tag_str
, &blockquote_elem
);
1781 nsAString_Finish(&tag_str
);
1783 nsAString_Init(&tag_str
, pW
);
1784 nsIDOMDocument_CreateElement(nsdoc
, &tag_str
, &p_elem
);
1785 nsAString_Finish(&tag_str
);
1787 nsIDOMDocument_Release(nsdoc
);
1789 nsIDOMRange_ExtractContents(This
->nsrange
, &fragment
);
1790 nsIDOMElement_AppendChild(p_elem
, (nsIDOMNode
*)fragment
, &tmp
);
1791 nsIDOMDocumentFragment_Release(fragment
);
1792 nsIDOMNode_Release(tmp
);
1794 nsIDOMElement_AppendChild(blockquote_elem
, (nsIDOMNode
*)p_elem
, &tmp
);
1795 nsIDOMElement_Release(p_elem
);
1796 nsIDOMNode_Release(tmp
);
1798 nsIDOMRange_InsertNode(This
->nsrange
, (nsIDOMNode
*)blockquote_elem
);
1799 nsIDOMElement_Release(blockquote_elem
);
1804 static HRESULT WINAPI
RangeCommandTarget_Exec(IOleCommandTarget
*iface
, const GUID
*pguidCmdGroup
,
1805 DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
1807 HTMLTxtRange
*This
= OLECMDTRG_THIS(iface
);
1809 TRACE("(%p)->(%s %d %x %p %p)\n", This
, debugstr_guid(pguidCmdGroup
), nCmdID
,
1810 nCmdexecopt
, pvaIn
, pvaOut
);
1812 if(pguidCmdGroup
&& IsEqualGUID(&CGID_MSHTML
, pguidCmdGroup
)) {
1815 return exec_indent(This
, pvaIn
, pvaOut
);
1817 FIXME("Unsupported cmdid %d of CGID_MSHTML\n", nCmdID
);
1820 FIXME("Unsupported cmd %d of group %s\n", nCmdID
, debugstr_guid(pguidCmdGroup
));
1826 #undef OLECMDTRG_THIS
1828 static const IOleCommandTargetVtbl OleCommandTargetVtbl
= {
1829 RangeCommandTarget_QueryInterface
,
1830 RangeCommandTarget_AddRef
,
1831 RangeCommandTarget_Release
,
1832 RangeCommandTarget_QueryStatus
,
1833 RangeCommandTarget_Exec
1836 IHTMLTxtRange
*HTMLTxtRange_Create(HTMLDocument
*doc
, nsIDOMRange
*nsrange
)
1838 HTMLTxtRange
*ret
= heap_alloc(sizeof(HTMLTxtRange
));
1840 ret
->lpHTMLTxtRangeVtbl
= &HTMLTxtRangeVtbl
;
1841 ret
->lpOleCommandTargetVtbl
= &OleCommandTargetVtbl
;
1845 nsIDOMRange_AddRef(nsrange
);
1846 ret
->nsrange
= nsrange
;
1849 list_add_head(&doc
->range_list
, &ret
->entry
);
1851 return HTMLTXTRANGE(ret
);
1854 void detach_ranges(HTMLDocument
*This
)
1858 LIST_FOR_EACH_ENTRY(iter
, &This
->range_list
, HTMLTxtRange
, entry
) {