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
;
52 #define HTMLTXTRANGE(x) ((IHTMLTxtRange*) &(x)->lpHTMLTxtRangeVtbl)
76 static HTMLTxtRange
*get_range_object(HTMLDocument
*doc
, IHTMLTxtRange
*iface
)
80 LIST_FOR_EACH_ENTRY(iter
, &doc
->range_list
, HTMLTxtRange
, entry
) {
81 if(HTMLTXTRANGE(iter
) == iface
)
85 ERR("Could not find range in document\n");
89 static range_unit_t
string_to_unit(LPCWSTR str
)
91 static const WCHAR characterW
[] =
92 {'c','h','a','r','a','c','t','e','r',0};
93 static const WCHAR wordW
[] =
95 static const WCHAR sentenceW
[] =
96 {'s','e','n','t','e','n','c','e',0};
97 static const WCHAR texteditW
[] =
98 {'t','e','x','t','e','d','i','t',0};
100 if(!strcmpiW(str
, characterW
)) return RU_CHAR
;
101 if(!strcmpiW(str
, wordW
)) return RU_WORD
;
102 if(!strcmpiW(str
, sentenceW
)) return RU_SENTENCE
;
103 if(!strcmpiW(str
, texteditW
)) return RU_TEXTEDIT
;
108 static int string_to_nscmptype(LPCWSTR str
)
110 static const WCHAR seW
[] = {'S','t','a','r','t','T','o','E','n','d',0};
111 static const WCHAR ssW
[] = {'S','t','a','r','t','T','o','S','t','a','r','t',0};
112 static const WCHAR esW
[] = {'E','n','d','T','o','S','t','a','r','t',0};
113 static const WCHAR eeW
[] = {'E','n','d','T','o','E','n','d',0};
115 if(!strcmpiW(str
, seW
)) return NS_START_TO_END
;
116 if(!strcmpiW(str
, ssW
)) return NS_START_TO_START
;
117 if(!strcmpiW(str
, esW
)) return NS_END_TO_START
;
118 if(!strcmpiW(str
, eeW
)) return NS_END_TO_END
;
123 static PRUint16
get_node_type(nsIDOMNode
*node
)
125 PRUint16 type
= 0xfff;
128 nsIDOMNode_GetNodeType(node
, &type
);
133 static BOOL
is_br_node(nsIDOMNode
*node
)
137 const PRUnichar
*tag
;
141 nsres
= nsIDOMNode_QueryInterface(node
, &IID_nsIDOMElement
, (void**)&elem
);
145 nsAString_Init(&tag_str
, NULL
);
146 nsIDOMElement_GetTagName(elem
, &tag_str
);
147 nsIDOMElement_Release(elem
);
148 nsAString_GetData(&tag_str
, &tag
, 0);
150 if(!strcmpiW(tag
, brW
))
153 nsAString_Finish(&tag_str
);
158 static inline void wstrbuf_init(wstrbuf_t
*buf
)
162 buf
->buf
= mshtml_alloc(buf
->size
* sizeof(WCHAR
));
166 static inline void wstrbuf_finish(wstrbuf_t
*buf
)
168 mshtml_free(buf
->buf
);
171 static void wstrbuf_append_len(wstrbuf_t
*buf
, LPCWSTR str
, int len
)
173 if(buf
->len
+len
>= buf
->size
) {
174 buf
->size
= 2*buf
->len
+len
;
175 buf
->buf
= mshtml_realloc(buf
->buf
, buf
->size
* sizeof(WCHAR
));
178 memcpy(buf
->buf
+buf
->len
, str
, len
*sizeof(WCHAR
));
180 buf
->buf
[buf
->len
] = 0;
183 static inline void wstrbuf_append(wstrbuf_t
*buf
, LPCWSTR str
)
185 wstrbuf_append_len(buf
, str
, strlenW(str
));
188 static void wstrbuf_append_node(wstrbuf_t
*buf
, nsIDOMNode
*node
)
191 switch(get_node_type(node
)) {
195 const PRUnichar
*data
;
197 nsIDOMNode_QueryInterface(node
, &IID_nsIDOMText
, (void**)&nstext
);
199 nsAString_Init(&data_str
, NULL
);
200 nsIDOMText_GetData(nstext
, &data_str
);
201 nsAString_GetData(&data_str
, &data
, NULL
);
202 wstrbuf_append(buf
, data
);
203 nsAString_Finish(&data_str
);
205 nsIDOMText_Release(nstext
);
210 if(is_br_node(node
)) {
211 static const WCHAR endlW
[] = {'\r','\n'};
212 wstrbuf_append_len(buf
, endlW
, 2);
217 static BOOL
fill_nodestr(dompos_t
*pos
)
222 if(pos
->type
!= TEXT_NODE
)
225 nsres
= nsIDOMNode_QueryInterface(pos
->node
, &IID_nsIDOMText
, (void**)&text
);
229 nsAString_Init(&pos
->str
, NULL
);
230 nsIDOMText_GetData(text
, &pos
->str
);
231 nsIDOMText_Release(text
);
232 nsAString_GetData(&pos
->str
, &pos
->p
, NULL
);
237 static nsIDOMNode
*next_node(nsIDOMNode
*iter
)
239 nsIDOMNode
*ret
, *tmp
;
245 nsres
= nsIDOMNode_GetFirstChild(iter
, &ret
);
246 if(NS_SUCCEEDED(nsres
) && ret
)
249 nsIDOMNode_AddRef(iter
);
252 nsres
= nsIDOMNode_GetNextSibling(iter
, &ret
);
253 if(NS_SUCCEEDED(nsres
) && ret
) {
254 nsIDOMNode_Release(iter
);
258 nsres
= nsIDOMNode_GetParentNode(iter
, &tmp
);
259 nsIDOMNode_Release(iter
);
261 }while(NS_SUCCEEDED(nsres
) && iter
);
266 static nsIDOMNode
*prev_node(HTMLTxtRange
*This
, nsIDOMNode
*iter
)
268 nsIDOMNode
*ret
, *tmp
;
272 nsIDOMHTMLDocument
*nshtmldoc
;
273 nsIDOMHTMLElement
*nselem
;
274 nsIDOMDocument
*nsdoc
;
276 nsIWebNavigation_GetDocument(This
->doc
->nscontainer
->navigation
, &nsdoc
);
277 nsIDOMDocument_QueryInterface(nsdoc
, &IID_nsIDOMHTMLDocument
, (void**)&nshtmldoc
);
278 nsIDOMDocument_Release(nsdoc
);
279 nsIDOMHTMLDocument_GetBody(nshtmldoc
, &nselem
);
280 nsIDOMHTMLDocument_Release(nshtmldoc
);
282 nsIDOMElement_GetLastChild(nselem
, &tmp
);
284 return (nsIDOMNode
*)nselem
;
288 nsIDOMNode_GetLastChild(ret
, &tmp
);
291 nsIDOMElement_Release(nselem
);
296 nsres
= nsIDOMNode_GetLastChild(iter
, &ret
);
297 if(NS_SUCCEEDED(nsres
) && ret
)
300 nsIDOMNode_AddRef(iter
);
303 nsres
= nsIDOMNode_GetPreviousSibling(iter
, &ret
);
304 if(NS_SUCCEEDED(nsres
) && ret
) {
305 nsIDOMNode_Release(iter
);
309 nsres
= nsIDOMNode_GetParentNode(iter
, &tmp
);
310 nsIDOMNode_Release(iter
);
312 }while(NS_SUCCEEDED(nsres
) && iter
);
317 static nsIDOMNode
*get_child_node(nsIDOMNode
*node
, PRUint32 off
)
319 nsIDOMNodeList
*node_list
;
320 nsIDOMNode
*ret
= NULL
;
322 nsIDOMNode_GetChildNodes(node
, &node_list
);
323 nsIDOMNodeList_Item(node_list
, off
, &ret
);
324 nsIDOMNodeList_Release(node_list
);
329 static void get_cur_pos(HTMLTxtRange
*This
, BOOL start
, dompos_t
*pos
)
338 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
343 nsIDOMRange_GetStartContainer(This
->nsrange
, &node
);
344 nsIDOMRange_GetStartOffset(This
->nsrange
, &off
);
346 nsIDOMRange_GetEndContainer(This
->nsrange
, &node
);
347 nsIDOMRange_GetEndOffset(This
->nsrange
, &off
);
350 pos
->type
= get_node_type(node
);
351 if(pos
->type
== ELEMENT_NODE
) {
353 pos
->node
= get_child_node(node
, off
);
356 pos
->node
= off
? get_child_node(node
, off
-1) : prev_node(This
, node
);
360 pos
->type
= get_node_type(pos
->node
);
361 nsIDOMNode_Release(node
);
369 pos
->node
= prev_node(This
, node
);
371 nsIDOMNode_Release(node
);
374 if(pos
->type
== TEXT_NODE
)
378 static void set_range_pos(HTMLTxtRange
*This
, BOOL start
, dompos_t
*pos
)
383 if(pos
->type
== TEXT_NODE
)
384 nsres
= nsIDOMRange_SetStart(This
->nsrange
, pos
->node
, pos
->off
);
386 nsres
= nsIDOMRange_SetStartBefore(This
->nsrange
, pos
->node
);
388 if(pos
->type
== TEXT_NODE
)
389 nsres
= nsIDOMRange_SetEnd(This
->nsrange
, pos
->node
, pos
->off
+1);
391 nsres
= nsIDOMRange_SetEndAfter(This
->nsrange
, pos
->node
);
395 ERR("failed: %p %08x\n", pos
->node
, nsres
);
398 static inline void dompos_release(dompos_t
*pos
)
401 nsIDOMNode_Release(pos
->node
);
404 nsAString_Finish(&pos
->str
);
407 static inline void dompos_addref(dompos_t
*pos
)
410 nsIDOMNode_AddRef(pos
->node
);
412 if(pos
->type
== TEXT_NODE
)
416 static void range_to_string(HTMLTxtRange
*This
, wstrbuf_t
*buf
)
418 nsIDOMNode
*iter
, *tmp
;
419 dompos_t start_pos
, end_pos
;
422 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
430 get_cur_pos(This
, FALSE
, &end_pos
);
431 get_cur_pos(This
, TRUE
, &start_pos
);
433 if(start_pos
.type
== TEXT_NODE
) {
434 if(start_pos
.node
== end_pos
.node
) {
435 wstrbuf_append_len(buf
, start_pos
.p
+start_pos
.off
, end_pos
.off
-start_pos
.off
+1);
436 iter
= start_pos
.node
;
437 nsIDOMNode_AddRef(iter
);
439 wstrbuf_append(buf
, start_pos
.p
+start_pos
.off
);
440 iter
= next_node(start_pos
.node
);
443 iter
= start_pos
.node
;
444 nsIDOMNode_AddRef(iter
);
447 while(iter
!= end_pos
.node
) {
448 wstrbuf_append_node(buf
, iter
);
449 tmp
= next_node(iter
);
450 nsIDOMNode_Release(iter
);
454 nsIDOMNode_AddRef(end_pos
.node
);
456 if(start_pos
.node
!= end_pos
.node
&& !is_br_node(end_pos
.node
))
457 wstrbuf_append_len(buf
, end_pos
.p
, end_pos
.off
+1);
459 nsIDOMNode_Release(iter
);
460 dompos_release(&start_pos
);
461 dompos_release(&end_pos
);
464 static WCHAR
get_pos_char(const dompos_t
*pos
)
468 return pos
->p
[pos
->off
];
470 if(is_br_node(pos
->node
))
477 static WCHAR
next_char(const dompos_t
*pos
, dompos_t
*new_pos
)
479 nsIDOMNode
*iter
, *tmp
;
481 if(pos
->type
== TEXT_NODE
&& pos
->off
!= -1 && pos
->p
[pos
->off
+1]) {
484 dompos_addref(new_pos
);
485 return new_pos
->p
[new_pos
->off
];
488 iter
= next_node(pos
->node
);
493 switch(get_node_type(iter
)) {
495 new_pos
->node
= iter
;
496 new_pos
->type
= TEXT_NODE
;
498 fill_nodestr(new_pos
);
502 if(!is_br_node(iter
))
505 new_pos
->node
= iter
;
506 new_pos
->type
= ELEMENT_NODE
;
513 iter
= next_node(iter
);
514 nsIDOMNode_Release(tmp
);
523 static WCHAR
prev_char(HTMLTxtRange
*This
, const dompos_t
*pos
, dompos_t
*new_pos
)
525 nsIDOMNode
*iter
, *tmp
;
527 if(pos
->type
== TEXT_NODE
&& pos
->off
> 0) {
530 dompos_addref(new_pos
);
531 return new_pos
->p
[new_pos
->off
];
534 iter
= prev_node(This
, pos
->node
);
539 switch(get_node_type(iter
)) {
541 new_pos
->node
= iter
;
542 new_pos
->type
= TEXT_NODE
;
543 fill_nodestr(new_pos
);
544 new_pos
->off
= strlenW(new_pos
->p
)-1;
545 return new_pos
->p
[new_pos
->off
];
548 if(!is_br_node(iter
))
551 new_pos
->node
= iter
;
552 new_pos
->type
= ELEMENT_NODE
;
559 iter
= prev_node(This
, iter
);
560 nsIDOMNode_Release(tmp
);
567 dompos_addref(new_pos
);
571 static long move_next_chars(long cnt
, const dompos_t
*pos
, BOOL col
, dompos_t
*new_pos
)
582 dompos_addref(new_pos
);
586 c
= next_char(pos
, &iter
);
591 c
= next_char(&tmp
, &iter
);
597 dompos_release(&tmp
);
604 static long move_prev_chars(HTMLTxtRange
*This
, long cnt
, const dompos_t
*pos
, BOOL end
, dompos_t
*new_pos
)
610 c
= prev_char(This
, pos
, &iter
);
614 while(c
&& ret
< cnt
) {
616 c
= prev_char(This
, &tmp
, &iter
);
624 dompos_release(&tmp
);
631 static BOOL
find_next_space(const dompos_t
*pos
, BOOL first_space
, dompos_t
*ret
)
637 c
= get_pos_char(pos
);
638 if(c
&& isspaceW(c
)) {
645 c
= next_char(pos
, &iter
);
652 while(!isspaceW(c
)) {
654 c
= next_char(&tmp
, &iter
);
659 dompos_release(&tmp
);
666 static long find_prev_space(HTMLTxtRange
*This
, const dompos_t
*pos
, BOOL first_space
, dompos_t
*ret
)
671 c
= prev_char(This
, pos
, &iter
);
672 if(!c
|| (first_space
&& isspaceW(c
))) {
680 c
= prev_char(This
, &tmp
, &iter
);
681 if(!c
|| isspaceW(c
)) {
682 dompos_release(&iter
);
685 dompos_release(&tmp
);
692 static long move_next_words(long cnt
, const dompos_t
*pos
, dompos_t
*new_pos
)
698 dompos_addref(&iter
);
701 if(!find_next_space(&iter
, FALSE
, &tmp
))
705 dompos_release(&iter
);
713 static long move_prev_words(HTMLTxtRange
*This
, long cnt
, const dompos_t
*pos
, dompos_t
*new_pos
)
719 dompos_addref(&iter
);
722 if(!find_prev_space(This
, &iter
, FALSE
, &tmp
))
725 dompos_release(&iter
);
734 #define HTMLTXTRANGE_THIS(iface) DEFINE_THIS(HTMLTxtRange, HTMLTxtRange, iface)
736 static HRESULT WINAPI
HTMLTxtRange_QueryInterface(IHTMLTxtRange
*iface
, REFIID riid
, void **ppv
)
738 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
742 if(IsEqualGUID(&IID_IUnknown
, riid
)) {
743 TRACE("(%p)->(IID_IUnknown %p)\n", This
, ppv
);
744 *ppv
= HTMLTXTRANGE(This
);
745 }else if(IsEqualGUID(&IID_IDispatch
, riid
)) {
746 TRACE("(%p)->(IID_IDispatch %p)\n", This
, ppv
);
747 *ppv
= HTMLTXTRANGE(This
);
748 }else if(IsEqualGUID(&IID_IHTMLTxtRange
, riid
)) {
749 TRACE("(%p)->(IID_IHTMLTxtRange %p)\n", This
, ppv
);
750 *ppv
= HTMLTXTRANGE(This
);
754 IUnknown_AddRef((IUnknown
*)*ppv
);
758 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), ppv
);
759 return E_NOINTERFACE
;
762 static ULONG WINAPI
HTMLTxtRange_AddRef(IHTMLTxtRange
*iface
)
764 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
765 LONG ref
= InterlockedIncrement(&This
->ref
);
767 TRACE("(%p) ref=%d\n", This
, ref
);
772 static ULONG WINAPI
HTMLTxtRange_Release(IHTMLTxtRange
*iface
)
774 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
775 LONG ref
= InterlockedDecrement(&This
->ref
);
777 TRACE("(%p) ref=%d\n", This
, ref
);
781 nsISelection_Release(This
->nsrange
);
783 list_remove(&This
->entry
);
790 static HRESULT WINAPI
HTMLTxtRange_GetTypeInfoCount(IHTMLTxtRange
*iface
, UINT
*pctinfo
)
792 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
793 FIXME("(%p)->(%p)\n", This
, pctinfo
);
797 static HRESULT WINAPI
HTMLTxtRange_GetTypeInfo(IHTMLTxtRange
*iface
, UINT iTInfo
,
798 LCID lcid
, ITypeInfo
**ppTInfo
)
800 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
801 FIXME("(%p)->(%u %u %p)\n", This
, iTInfo
, lcid
, ppTInfo
);
805 static HRESULT WINAPI
HTMLTxtRange_GetIDsOfNames(IHTMLTxtRange
*iface
, REFIID riid
,
806 LPOLESTR
*rgszNames
, UINT cNames
,
807 LCID lcid
, DISPID
*rgDispId
)
809 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
810 FIXME("(%p)->(%s %p %u %u %p)\n", This
, debugstr_guid(riid
), rgszNames
, cNames
,
815 static HRESULT WINAPI
HTMLTxtRange_Invoke(IHTMLTxtRange
*iface
, DISPID dispIdMember
,
816 REFIID riid
, LCID lcid
, WORD wFlags
, DISPPARAMS
*pDispParams
,
817 VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
819 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
820 FIXME("(%p)->(%d %s %d %d %p %p %p %p)\n", This
, dispIdMember
, debugstr_guid(riid
),
821 lcid
, wFlags
, pDispParams
, pVarResult
, pExcepInfo
, puArgErr
);
825 static HRESULT WINAPI
HTMLTxtRange_get_htmlText(IHTMLTxtRange
*iface
, BSTR
*p
)
827 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
829 TRACE("(%p)->(%p)\n", This
, p
);
834 nsIDOMDocumentFragment
*fragment
;
837 nsres
= nsIDOMRange_CloneContents(This
->nsrange
, &fragment
);
838 if(NS_SUCCEEDED(nsres
)) {
839 const PRUnichar
*nstext
;
842 nsAString_Init(&nsstr
, NULL
);
843 nsnode_to_nsstring((nsIDOMNode
*)fragment
, &nsstr
);
844 nsIDOMDocumentFragment_Release(fragment
);
846 nsAString_GetData(&nsstr
, &nstext
, NULL
);
847 *p
= SysAllocString(nstext
);
849 nsAString_Finish(&nsstr
);
854 const WCHAR emptyW
[] = {0};
855 *p
= SysAllocString(emptyW
);
858 TRACE("return %s\n", debugstr_w(*p
));
862 static HRESULT WINAPI
HTMLTxtRange_put_text(IHTMLTxtRange
*iface
, BSTR v
)
864 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
865 nsIDOMDocument
*nsdoc
;
866 nsIDOMText
*text_node
;
870 TRACE("(%p)->(%s)\n", This
, debugstr_w(v
));
873 return MSHTML_E_NODOC
;
875 nsres
= nsIWebNavigation_GetDocument(This
->doc
->nscontainer
->navigation
, &nsdoc
);
876 if(NS_FAILED(nsres
)) {
877 ERR("GetDocument failed: %08x\n", nsres
);
881 nsAString_Init(&text_str
, v
);
882 nsres
= nsIDOMDocument_CreateTextNode(nsdoc
, &text_str
, &text_node
);
883 nsAString_Finish(&text_str
);
884 if(NS_FAILED(nsres
)) {
885 ERR("CreateTextNode failed: %08x\n", nsres
);
888 nsres
= nsIDOMRange_DeleteContents(This
->nsrange
);
890 ERR("DeleteContents failed: %08x\n", nsres
);
892 nsres
= nsIDOMRange_InsertNode(This
->nsrange
, (nsIDOMNode
*)text_node
);
894 ERR("InsertNode failed: %08x\n", nsres
);
899 static HRESULT WINAPI
HTMLTxtRange_get_text(IHTMLTxtRange
*iface
, BSTR
*p
)
901 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
904 TRACE("(%p)->(%p)\n", This
, p
);
911 range_to_string(This
, &buf
);
913 *p
= SysAllocString(buf
.buf
);
914 wstrbuf_finish(&buf
);
916 TRACE("ret %s\n", debugstr_w(*p
));
920 static HRESULT WINAPI
HTMLTxtRange_parentElement(IHTMLTxtRange
*iface
, IHTMLElement
**parent
)
922 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
923 nsIDOMNode
*nsnode
, *tmp
;
926 TRACE("(%p)->(%p)\n", This
, parent
);
928 nsIDOMRange_GetCommonAncestorContainer(This
->nsrange
, &nsnode
);
929 while(nsnode
&& get_node_type(nsnode
) != ELEMENT_NODE
) {
930 nsIDOMNode_GetParentNode(nsnode
, &tmp
);
931 nsIDOMNode_Release(nsnode
);
940 node
= get_node(This
->doc
, nsnode
);
941 nsIDOMNode_Release(nsnode
);
943 return IHTMLDOMNode_QueryInterface(HTMLDOMNODE(node
), &IID_IHTMLElement
, (void**)parent
);
946 static HRESULT WINAPI
HTMLTxtRange_duplicate(IHTMLTxtRange
*iface
, IHTMLTxtRange
**Duplicate
)
948 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
949 nsIDOMRange
*nsrange
= NULL
;
951 TRACE("(%p)->(%p)\n", This
, Duplicate
);
953 nsIDOMRange_CloneRange(This
->nsrange
, &nsrange
);
954 *Duplicate
= HTMLTxtRange_Create(This
->doc
, nsrange
);
955 nsIDOMRange_Release(nsrange
);
960 static HRESULT WINAPI
HTMLTxtRange_inRange(IHTMLTxtRange
*iface
, IHTMLTxtRange
*Range
,
961 VARIANT_BOOL
*InRange
)
963 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
964 HTMLTxtRange
*src_range
;
968 TRACE("(%p)->(%p %p)\n", This
, Range
, InRange
);
970 *InRange
= VARIANT_FALSE
;
972 src_range
= get_range_object(This
->doc
, Range
);
976 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, NS_START_TO_START
,
977 src_range
->nsrange
, &nsret
);
978 if(NS_SUCCEEDED(nsres
) && nsret
<= 0) {
979 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, NS_END_TO_END
,
980 src_range
->nsrange
, &nsret
);
981 if(NS_SUCCEEDED(nsres
) && nsret
>= 0)
982 *InRange
= VARIANT_TRUE
;
986 ERR("CompareBoundaryPoints failed: %08x\n", nsres
);
991 static HRESULT WINAPI
HTMLTxtRange_isEqual(IHTMLTxtRange
*iface
, IHTMLTxtRange
*Range
,
992 VARIANT_BOOL
*IsEqual
)
994 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
995 HTMLTxtRange
*src_range
;
999 TRACE("(%p)->(%p %p)\n", This
, Range
, IsEqual
);
1001 *IsEqual
= VARIANT_FALSE
;
1003 src_range
= get_range_object(This
->doc
, Range
);
1007 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, NS_START_TO_START
,
1008 src_range
->nsrange
, &nsret
);
1009 if(NS_SUCCEEDED(nsres
) && !nsret
) {
1010 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, NS_END_TO_END
,
1011 src_range
->nsrange
, &nsret
);
1012 if(NS_SUCCEEDED(nsres
) && !nsret
)
1013 *IsEqual
= VARIANT_TRUE
;
1016 if(NS_FAILED(nsres
))
1017 ERR("CompareBoundaryPoints failed: %08x\n", nsres
);
1022 static HRESULT WINAPI
HTMLTxtRange_scrollIntoView(IHTMLTxtRange
*iface
, VARIANT_BOOL fStart
)
1024 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1025 FIXME("(%p)->(%x)\n", This
, fStart
);
1029 static HRESULT WINAPI
HTMLTxtRange_collapse(IHTMLTxtRange
*iface
, VARIANT_BOOL Start
)
1031 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1033 TRACE("(%p)->(%x)\n", This
, Start
);
1035 nsIDOMRange_Collapse(This
->nsrange
, Start
!= VARIANT_FALSE
);
1039 static HRESULT WINAPI
HTMLTxtRange_expand(IHTMLTxtRange
*iface
, BSTR Unit
, VARIANT_BOOL
*Success
)
1041 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1044 TRACE("(%p)->(%s %p)\n", This
, debugstr_w(Unit
), Success
);
1046 unit
= string_to_unit(Unit
);
1047 if(unit
== RU_UNKNOWN
)
1048 return E_INVALIDARG
;
1052 dompos_t end_pos
, start_pos
, new_pos
;
1054 *Success
= VARIANT_FALSE
;
1056 get_cur_pos(This
, TRUE
, &start_pos
);
1057 get_cur_pos(This
, FALSE
, &end_pos
);
1058 if(find_next_space(&end_pos
, TRUE
, &new_pos
)) {
1059 set_range_pos(This
, FALSE
, &new_pos
);
1060 *Success
= VARIANT_TRUE
;
1062 dompos_release(&new_pos
);
1064 if(find_prev_space(This
, &start_pos
, TRUE
, &new_pos
)) {
1065 set_range_pos(This
, TRUE
, &new_pos
);
1066 *Success
= VARIANT_TRUE
;
1069 dompos_release(&new_pos
);
1070 dompos_release(&end_pos
);
1075 FIXME("Unimplemented unit %s\n", debugstr_w(Unit
));
1081 static HRESULT WINAPI
HTMLTxtRange_move(IHTMLTxtRange
*iface
, BSTR Unit
,
1082 long Count
, long *ActualCount
)
1084 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1087 TRACE("(%p)->(%s %ld %p)\n", This
, debugstr_w(Unit
), Count
, ActualCount
);
1089 unit
= string_to_unit(Unit
);
1090 if(unit
== RU_UNKNOWN
)
1091 return E_INVALIDARG
;
1093 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), TRUE
);
1102 dompos_t cur_pos
, new_pos
;
1104 get_cur_pos(This
, TRUE
, &cur_pos
);
1107 *ActualCount
= move_next_chars(Count
, &cur_pos
, TRUE
, &new_pos
);
1108 set_range_pos(This
, FALSE
, &new_pos
);
1109 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), FALSE
);
1110 dompos_release(&new_pos
);
1112 *ActualCount
= -move_prev_chars(This
, -Count
, &cur_pos
, FALSE
, &new_pos
);
1113 set_range_pos(This
, TRUE
, &new_pos
);
1114 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), TRUE
);
1115 dompos_release(&new_pos
);
1118 dompos_release(&cur_pos
);
1123 dompos_t cur_pos
, new_pos
;
1125 get_cur_pos(This
, TRUE
, &cur_pos
);
1128 *ActualCount
= move_next_words(Count
, &cur_pos
, &new_pos
);
1129 set_range_pos(This
, FALSE
, &new_pos
);
1130 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), FALSE
);
1131 dompos_release(&new_pos
);
1133 *ActualCount
= -move_prev_words(This
, -Count
, &cur_pos
, &new_pos
);
1134 set_range_pos(This
, TRUE
, &new_pos
);
1135 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), TRUE
);
1136 dompos_release(&new_pos
);
1139 dompos_release(&cur_pos
);
1144 FIXME("unimplemented unit %s\n", debugstr_w(Unit
));
1147 TRACE("ret %ld\n", *ActualCount
);
1151 static HRESULT WINAPI
HTMLTxtRange_moveStart(IHTMLTxtRange
*iface
, BSTR Unit
,
1152 long Count
, long *ActualCount
)
1154 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1155 FIXME("(%p)->(%s %ld %p)\n", This
, debugstr_w(Unit
), Count
, ActualCount
);
1159 static HRESULT WINAPI
HTMLTxtRange_moveEnd(IHTMLTxtRange
*iface
, BSTR Unit
,
1160 long Count
, long *ActualCount
)
1162 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1165 TRACE("(%p)->(%s %ld %p)\n", This
, debugstr_w(Unit
), Count
, ActualCount
);
1167 unit
= string_to_unit(Unit
);
1168 if(unit
== RU_UNKNOWN
)
1169 return E_INVALIDARG
;
1178 dompos_t cur_pos
, new_pos
;
1181 get_cur_pos(This
, FALSE
, &cur_pos
);
1182 nsIDOMRange_GetCollapsed(This
->nsrange
, &collapsed
);
1185 *ActualCount
= move_next_chars(Count
, &cur_pos
, collapsed
, &new_pos
);
1186 set_range_pos(This
, FALSE
, &new_pos
);
1188 *ActualCount
= -move_prev_chars(This
, -Count
, &cur_pos
, TRUE
, &new_pos
);
1189 if(*ActualCount
== Count
)
1190 set_range_pos(This
, FALSE
, &new_pos
);
1192 IHTMLTxtRange_collapse(HTMLTXTRANGE(This
), TRUE
);
1195 dompos_release(&cur_pos
);
1196 dompos_release(&new_pos
);
1201 FIXME("unimplemented unit %s\n", debugstr_w(Unit
));
1207 static HRESULT WINAPI
HTMLTxtRange_select(IHTMLTxtRange
*iface
)
1209 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1211 TRACE("(%p)\n", This
);
1213 if(This
->doc
->nscontainer
) {
1214 nsIDOMWindow
*dom_window
= NULL
;
1215 nsISelection
*nsselection
;
1217 nsIWebBrowser_GetContentDOMWindow(This
->doc
->nscontainer
->webbrowser
, &dom_window
);
1218 nsIDOMWindow_GetSelection(dom_window
, &nsselection
);
1219 nsIDOMWindow_Release(dom_window
);
1221 nsISelection_RemoveAllRanges(nsselection
);
1222 nsISelection_AddRange(nsselection
, This
->nsrange
);
1224 nsISelection_Release(nsselection
);
1230 static HRESULT WINAPI
HTMLTxtRange_pasteHTML(IHTMLTxtRange
*iface
, BSTR html
)
1232 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1233 FIXME("(%p)->(%s)\n", This
, debugstr_w(html
));
1237 static HRESULT WINAPI
HTMLTxtRange_moveToElementText(IHTMLTxtRange
*iface
, IHTMLElement
*element
)
1239 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1240 FIXME("(%p)->(%p)\n", This
, element
);
1244 static HRESULT WINAPI
HTMLTxtRange_setEndPoint(IHTMLTxtRange
*iface
, BSTR how
,
1245 IHTMLTxtRange
*SourceRange
)
1247 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1248 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(how
), SourceRange
);
1252 static HRESULT WINAPI
HTMLTxtRange_compareEndPoints(IHTMLTxtRange
*iface
, BSTR how
,
1253 IHTMLTxtRange
*SourceRange
, long *ret
)
1255 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1256 HTMLTxtRange
*src_range
;
1261 TRACE("(%p)->(%s %p %p)\n", This
, debugstr_w(how
), SourceRange
, ret
);
1263 nscmpt
= string_to_nscmptype(how
);
1265 return E_INVALIDARG
;
1267 src_range
= get_range_object(This
->doc
, SourceRange
);
1271 nsres
= nsIDOMRange_CompareBoundaryPoints(This
->nsrange
, nscmpt
, src_range
->nsrange
, &nsret
);
1272 if(NS_FAILED(nsres
))
1273 ERR("CompareBoundaryPoints failed: %08x\n", nsres
);
1279 static HRESULT WINAPI
HTMLTxtRange_findText(IHTMLTxtRange
*iface
, BSTR String
,
1280 long count
, long Flags
, VARIANT_BOOL
*Success
)
1282 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1283 FIXME("(%p)->(%s %ld %08lx %p)\n", This
, debugstr_w(String
), count
, Flags
, Success
);
1287 static HRESULT WINAPI
HTMLTxtRange_moveToPoint(IHTMLTxtRange
*iface
, long x
, long y
)
1289 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1290 FIXME("(%p)->(%ld %ld)\n", This
, x
, y
);
1294 static HRESULT WINAPI
HTMLTxtRange_getBookmark(IHTMLTxtRange
*iface
, BSTR
*Bookmark
)
1296 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1297 FIXME("(%p)->(%p)\n", This
, Bookmark
);
1301 static HRESULT WINAPI
HTMLTxtRange_moveToBookmark(IHTMLTxtRange
*iface
, BSTR Bookmark
,
1302 VARIANT_BOOL
*Success
)
1304 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1305 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(Bookmark
), Success
);
1309 static HRESULT WINAPI
HTMLTxtRange_queryCommandSupported(IHTMLTxtRange
*iface
, BSTR cmdID
,
1310 VARIANT_BOOL
*pfRet
)
1312 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1313 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1317 static HRESULT WINAPI
HTMLTxtRange_queryCommandEnabled(IHTMLTxtRange
*iface
, BSTR cmdID
,
1318 VARIANT_BOOL
*pfRet
)
1320 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1321 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1325 static HRESULT WINAPI
HTMLTxtRange_queryCommandState(IHTMLTxtRange
*iface
, BSTR cmdID
,
1326 VARIANT_BOOL
*pfRet
)
1328 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1329 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1333 static HRESULT WINAPI
HTMLTxtRange_queryCommandIndeterm(IHTMLTxtRange
*iface
, BSTR cmdID
,
1334 VARIANT_BOOL
*pfRet
)
1336 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1337 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1341 static HRESULT WINAPI
HTMLTxtRange_queryCommandText(IHTMLTxtRange
*iface
, BSTR cmdID
,
1344 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1345 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pcmdText
);
1349 static HRESULT WINAPI
HTMLTxtRange_queryCommandValue(IHTMLTxtRange
*iface
, BSTR cmdID
,
1352 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1353 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pcmdValue
);
1357 static HRESULT WINAPI
HTMLTxtRange_execCommand(IHTMLTxtRange
*iface
, BSTR cmdID
,
1358 VARIANT_BOOL showUI
, VARIANT value
, VARIANT_BOOL
*pfRet
)
1360 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1361 FIXME("(%p)->(%s %x v %p)\n", This
, debugstr_w(cmdID
), showUI
, pfRet
);
1365 static HRESULT WINAPI
HTMLTxtRange_execCommandShowHelp(IHTMLTxtRange
*iface
, BSTR cmdID
,
1366 VARIANT_BOOL
*pfRet
)
1368 HTMLTxtRange
*This
= HTMLTXTRANGE_THIS(iface
);
1369 FIXME("(%p)->(%s %p)\n", This
, debugstr_w(cmdID
), pfRet
);
1373 #undef HTMLTXTRANGE_THIS
1375 static const IHTMLTxtRangeVtbl HTMLTxtRangeVtbl
= {
1376 HTMLTxtRange_QueryInterface
,
1377 HTMLTxtRange_AddRef
,
1378 HTMLTxtRange_Release
,
1379 HTMLTxtRange_GetTypeInfoCount
,
1380 HTMLTxtRange_GetTypeInfo
,
1381 HTMLTxtRange_GetIDsOfNames
,
1382 HTMLTxtRange_Invoke
,
1383 HTMLTxtRange_get_htmlText
,
1384 HTMLTxtRange_put_text
,
1385 HTMLTxtRange_get_text
,
1386 HTMLTxtRange_parentElement
,
1387 HTMLTxtRange_duplicate
,
1388 HTMLTxtRange_inRange
,
1389 HTMLTxtRange_isEqual
,
1390 HTMLTxtRange_scrollIntoView
,
1391 HTMLTxtRange_collapse
,
1392 HTMLTxtRange_expand
,
1394 HTMLTxtRange_moveStart
,
1395 HTMLTxtRange_moveEnd
,
1396 HTMLTxtRange_select
,
1397 HTMLTxtRange_pasteHTML
,
1398 HTMLTxtRange_moveToElementText
,
1399 HTMLTxtRange_setEndPoint
,
1400 HTMLTxtRange_compareEndPoints
,
1401 HTMLTxtRange_findText
,
1402 HTMLTxtRange_moveToPoint
,
1403 HTMLTxtRange_getBookmark
,
1404 HTMLTxtRange_moveToBookmark
,
1405 HTMLTxtRange_queryCommandSupported
,
1406 HTMLTxtRange_queryCommandEnabled
,
1407 HTMLTxtRange_queryCommandState
,
1408 HTMLTxtRange_queryCommandIndeterm
,
1409 HTMLTxtRange_queryCommandText
,
1410 HTMLTxtRange_queryCommandValue
,
1411 HTMLTxtRange_execCommand
,
1412 HTMLTxtRange_execCommandShowHelp
1415 IHTMLTxtRange
*HTMLTxtRange_Create(HTMLDocument
*doc
, nsIDOMRange
*nsrange
)
1417 HTMLTxtRange
*ret
= mshtml_alloc(sizeof(HTMLTxtRange
));
1419 ret
->lpHTMLTxtRangeVtbl
= &HTMLTxtRangeVtbl
;
1423 nsIDOMRange_AddRef(nsrange
);
1424 ret
->nsrange
= nsrange
;
1427 list_add_head(&doc
->range_list
, &ret
->entry
);
1429 return HTMLTXTRANGE(ret
);
1432 void detach_ranges(HTMLDocument
*This
)
1436 LIST_FOR_EACH_ENTRY(iter
, &This
->range_list
, HTMLTxtRange
, entry
) {