ReactOS 0.4.15-dev-7788-g1ad9096
txtrange.c
Go to the documentation of this file.
1/*
2 * Copyright 2006-2007 Jacek Caban for CodeWeavers
3 *
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.
8 *
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.
13 *
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
17 */
18
19#include "mshtml_private.h"
20
21static const WCHAR brW[] = {'b','r',0};
22static const WCHAR hrW[] = {'h','r',0};
23
24typedef struct {
26 IHTMLTxtRange IHTMLTxtRange_iface;
28
30
33
34 struct list entry;
36
37typedef struct {
41} wstrbuf_t;
42
43typedef struct {
48
49typedef enum {
56
57static HTMLTxtRange *get_range_object(HTMLDocumentNode *doc, IHTMLTxtRange *iface)
58{
59 HTMLTxtRange *iter;
60
62 if(&iter->IHTMLTxtRange_iface == iface)
63 return iter;
64 }
65
66 ERR("Could not find range in document\n");
67 return NULL;
68}
69
71{
72 static const WCHAR characterW[] =
73 {'c','h','a','r','a','c','t','e','r',0};
74 static const WCHAR wordW[] =
75 {'w','o','r','d',0};
76 static const WCHAR sentenceW[] =
77 {'s','e','n','t','e','n','c','e',0};
78 static const WCHAR texteditW[] =
79 {'t','e','x','t','e','d','i','t',0};
80
81 if(!strcmpiW(str, characterW)) return RU_CHAR;
82 if(!strcmpiW(str, wordW)) return RU_WORD;
83 if(!strcmpiW(str, sentenceW)) return RU_SENTENCE;
84 if(!strcmpiW(str, texteditW)) return RU_TEXTEDIT;
85
86 return RU_UNKNOWN;
87}
88
90{
91 static const WCHAR seW[] = {'S','t','a','r','t','T','o','E','n','d',0};
92 static const WCHAR ssW[] = {'S','t','a','r','t','T','o','S','t','a','r','t',0};
93 static const WCHAR esW[] = {'E','n','d','T','o','S','t','a','r','t',0};
94 static const WCHAR eeW[] = {'E','n','d','T','o','E','n','d',0};
95
96 if(!strcmpiW(str, seW)) return NS_START_TO_END;
97 if(!strcmpiW(str, ssW)) return NS_START_TO_START;
98 if(!strcmpiW(str, esW)) return NS_END_TO_START;
99 if(!strcmpiW(str, eeW)) return NS_END_TO_END;
100
101 return -1;
102}
103
105{
106 UINT16 type = 0;
107
108 if(node)
109 nsIDOMNode_GetNodeType(node, &type);
110
111 return type;
112}
113
115{
116 nsIDOMText *nstext;
117 nsresult nsres;
118
119 nsres = nsIDOMNode_QueryInterface(node, &IID_nsIDOMText, (void**)&nstext);
120 assert(nsres == NS_OK);
121
122 nsAString_Init(nsstr, NULL);
123 nsres = nsIDOMText_GetData(nstext, nsstr);
124 nsIDOMText_Release(nstext);
125 if(NS_FAILED(nsres))
126 ERR("GetData failed: %08x\n", nsres);
127
128 nsAString_GetData(nsstr, str);
129}
130
132{
133 nsIDOMNodeList *node_list;
135
136 nsIDOMNode_GetChildNodes(node, &node_list);
137 nsIDOMNodeList_Item(node_list, off, &ret);
138 nsIDOMNodeList_Release(node_list);
139
140 return ret;
141}
142
143/* This is very inefficient, but there is no faster way to compute index in
144 * child node list using public API. Gecko has internal nsINode::IndexOf
145 * function that we could consider exporting and use instead. */
147{
148 nsIDOMNodeList *node_list;
150 int ret = 0;
151 nsresult nsres;
152
153 nsres = nsIDOMNode_GetChildNodes(parent, &node_list);
154 assert(nsres == NS_OK);
155
156 while(1) {
157 nsres = nsIDOMNodeList_Item(node_list, ret, &node);
158 assert(nsres == NS_OK && node);
159 if(node == child) {
160 nsIDOMNode_Release(node);
161 break;
162 }
163 nsIDOMNode_Release(node);
164 ret++;
165 }
166
167 nsIDOMNodeList_Release(node_list);
168 return ret;
169}
170
171static void init_rangepoint(rangepoint_t *rangepoint, nsIDOMNode *node, UINT32 off)
172{
173 nsIDOMNode_AddRef(node);
174
175 rangepoint->type = get_node_type(node);
176 rangepoint->node = node;
177 rangepoint->off = off;
178}
179
180static inline void free_rangepoint(rangepoint_t *rangepoint)
181{
182 nsIDOMNode_Release(rangepoint->node);
183}
184
185static inline BOOL rangepoint_cmp(const rangepoint_t *point1, const rangepoint_t *point2)
186{
187 return point1->node == point2->node && point1->off == point2->off;
188}
189
191{
193 UINT32 off;
194 nsresult nsres;
195
196 /* Try to move to the child node. */
197 node = get_child_node(iter->node, iter->off);
198 if(node) {
199 free_rangepoint(iter);
200 init_rangepoint(iter, node, 0);
201 nsIDOMNode_Release(node);
202 return TRUE;
203 }
204
205 /* There are no more children in the node. Move to parent. */
206 nsres = nsIDOMNode_GetParentNode(iter->node, &node);
207 assert(nsres == NS_OK);
208 if(!node)
209 return FALSE;
210
211 off = get_child_index(node, iter->node)+1;
212 free_rangepoint(iter);
213 init_rangepoint(iter, node, off);
214 nsIDOMNode_Release(node);
215 return TRUE;
216}
217
219{
220 nsIDOMNodeList *node_list;
221 UINT32 ret;
222 nsresult nsres;
223
224 nsres = nsIDOMNode_GetChildNodes(node, &node_list);
225 assert(nsres == NS_OK);
226
227 nsres = nsIDOMNodeList_GetLength(node_list, &ret);
228 nsIDOMNodeList_Release(node_list);
229 assert(nsres == NS_OK);
230
231 return ret;
232}
233
235{
236 nsIDOMText *nstext;
237 UINT32 ret;
238 nsresult nsres;
239
240 nsres = nsIDOMNode_QueryInterface(node, &IID_nsIDOMText, (void**)&nstext);
241 assert(nsres == NS_OK);
242
243 nsres = nsIDOMText_GetLength(nstext, &ret);
244 nsIDOMText_Release(nstext);
245 assert(nsres == NS_OK);
246
247 return ret;
248}
249
251{
253 UINT32 off;
254 nsresult nsres;
255
256 /* Try to move to the child node. */
257 if(iter->off) {
258 node = get_child_node(iter->node, iter->off-1);
259 assert(node != NULL);
260
261 off = get_node_type(node) == TEXT_NODE ? get_text_length(node) : get_child_count(node);
262 free_rangepoint(iter);
263 init_rangepoint(iter, node, off);
264 nsIDOMNode_Release(node);
265 return TRUE;
266 }
267
268 /* There are no more children in the node. Move to parent. */
269 nsres = nsIDOMNode_GetParentNode(iter->node, &node);
270 assert(nsres == NS_OK);
271 if(!node)
272 return FALSE;
273
274 off = get_child_index(node, iter->node);
275 free_rangepoint(iter);
276 init_rangepoint(iter, node, off);
277 return TRUE;
278}
279
281{
283 LONG off;
284
285 nsIDOMRange_GetStartContainer(This->nsrange, &node);
286 nsIDOMRange_GetStartOffset(This->nsrange, &off);
287
288 init_rangepoint(ret, node, off);
289
290 nsIDOMNode_Release(node);
291}
292
294{
296 LONG off;
297
298 nsIDOMRange_GetEndContainer(This->nsrange, &node);
299 nsIDOMRange_GetEndOffset(This->nsrange, &off);
300
301 init_rangepoint(ret, node, off);
302
303 nsIDOMNode_Release(node);
304}
305
307{
308 nsresult nsres = nsIDOMRange_SetStart(This->nsrange, start->node, start->off);
309 if(NS_FAILED(nsres))
310 ERR("failed: %08x\n", nsres);
311}
312
314{
315 nsresult nsres = nsIDOMRange_SetEnd(This->nsrange, end->node, end->off);
316 if(NS_FAILED(nsres))
317 ERR("failed: %08x\n", nsres);
318}
319
321{
323 nsAString tag_str;
324 const PRUnichar *tag;
325 BOOL ret = FALSE;
326 nsresult nsres;
327
328 nsres = nsIDOMNode_QueryInterface(node, &IID_nsIDOMElement, (void**)&elem);
329 if(NS_FAILED(nsres))
330 return FALSE;
331
332 nsAString_Init(&tag_str, NULL);
333 nsIDOMElement_GetTagName(elem, &tag_str);
334 nsIDOMElement_Release(elem);
335 nsAString_GetData(&tag_str, &tag);
336
337 ret = !strcmpiW(tag, istag);
338
339 nsAString_Finish(&tag_str);
340
341 return ret;
342}
343
345{
346 buf->len = 0;
347 buf->size = 16;
348 buf->buf = heap_alloc(buf->size * sizeof(WCHAR));
349 if (!buf->buf) return FALSE;
350 *buf->buf = 0;
351 return TRUE;
352}
353
354static inline void wstrbuf_finish(wstrbuf_t *buf)
355{
356 heap_free(buf->buf);
357}
358
360{
361 if(buf->len+len >= buf->size) {
362 buf->size = 2*buf->size+len;
363 buf->buf = heap_realloc(buf->buf, buf->size * sizeof(WCHAR));
364 }
365
366 memcpy(buf->buf+buf->len, str, len*sizeof(WCHAR));
367 buf->len += len;
368 buf->buf[buf->len] = 0;
369}
370
372{
373 const WCHAR *s = str;
374 WCHAR *d;
375
376 TRACE("%s\n", debugstr_wn(str, len));
377
378 if(buf->len+len >= buf->size) {
379 buf->size = 2*buf->size+len;
380 buf->buf = heap_realloc(buf->buf, buf->size * sizeof(WCHAR));
381 }
382
383 if(buf->len && isspaceW(buf->buf[buf->len-1])) {
384 while(s < str+len && isspaceW(*s))
385 s++;
386 }
387
388 d = buf->buf+buf->len;
389 while(s < str+len) {
390 if(isspaceW(*s)) {
391 *d++ = ' ';
392 s++;
393 while(s < str+len && isspaceW(*s))
394 s++;
395 }else {
396 *d++ = *s++;
397 }
398 }
399
400 buf->len = d - buf->buf;
401 *d = 0;
402}
403
405{
406
407 switch(get_node_type(node)) {
408 case TEXT_NODE: {
409 nsIDOMText *nstext;
410 nsAString data_str;
411 const PRUnichar *data;
412
413 if(ignore_text)
414 break;
415
416 nsIDOMNode_QueryInterface(node, &IID_nsIDOMText, (void**)&nstext);
417
418 nsAString_Init(&data_str, NULL);
419 nsIDOMText_GetData(nstext, &data_str);
420 nsAString_GetData(&data_str, &data);
422 nsAString_Finish(&data_str);
423
424 nsIDOMText_Release(nstext);
425
426 break;
427 }
428 case ELEMENT_NODE:
429 if(is_elem_tag(node, brW)) {
430 static const WCHAR endlW[] = {'\r','\n'};
431 wstrbuf_append_len(buf, endlW, 2);
432 }else if(is_elem_tag(node, hrW)) {
433 static const WCHAR endl2W[] = {'\r','\n','\r','\n'};
434 wstrbuf_append_len(buf, endl2W, 4);
435 }
436 }
437}
438
440{
441 nsIDOMNode *iter, *tmp;
442
444
445 nsIDOMNode_GetFirstChild(node, &iter);
446 while(iter) {
448 nsIDOMNode_GetNextSibling(iter, &tmp);
449 nsIDOMNode_Release(iter);
450 iter = tmp;
451 }
452}
453
455{
456 rangepoint_t end_pos, iter;
457 cpp_bool collapsed;
458
459 nsIDOMRange_GetCollapsed(This->nsrange, &collapsed);
460 if(collapsed) {
462 buf->buf = NULL;
463 buf->size = 0;
464 return;
465 }
466
467 get_end_point(This, &end_pos);
468 get_start_point(This, &iter);
469
470 do {
471 if(iter.type == TEXT_NODE) {
472 const PRUnichar *str;
473 nsAString nsstr;
474
475 get_text_node_data(iter.node, &nsstr, &str);
476
477 if(iter.node == end_pos.node) {
478 wstrbuf_append_nodetxt(buf, str+iter.off, end_pos.off-iter.off);
479 nsAString_Finish(&nsstr);
480 break;
481 }
482
484 nsAString_Finish(&nsstr);
485 }else {
487
488 node = get_child_node(iter.node, iter.off);
489 if(node) {
491 nsIDOMNode_Release(node);
492 }
493 }
494
495 if(!rangepoint_next_node(&iter)) {
496 ERR("End of document?\n");
497 break;
498 }
499 }while(!rangepoint_cmp(&iter, &end_pos));
500
501 free_rangepoint(&iter);
502 free_rangepoint(&end_pos);
503
504 if(buf->len) {
505 WCHAR *p;
506
507 for(p = buf->buf+buf->len-1; p >= buf->buf && isspaceW(*p); p--);
508
509 p = strchrW(p, '\r');
510 if(p)
511 *p = 0;
512 }
513}
514
516{
518 HRESULT hres = S_OK;
519
520 if (!wstrbuf_init(&buf))
521 return E_OUTOFMEMORY;
523 if(buf.buf) {
524 *ret = SysAllocString(buf.buf);
525 if(!*ret)
527 } else {
528 *ret = NULL;
529 }
531
532 if(SUCCEEDED(hres))
533 TRACE("ret %s\n", debugstr_w(*ret));
534 return hres;
535}
536
538{
539 rangepoint_t last_space;
541 WCHAR cspace = 0;
542 const WCHAR *p;
543
544 do {
545 switch(iter->type) {
546 case TEXT_NODE: {
547 const PRUnichar *str;
548 nsAString nsstr;
549 WCHAR c;
550
551 get_text_node_data(iter->node, &nsstr, &str);
552 p = str+iter->off;
553 if(!*p) {
554 nsAString_Finish(&nsstr);
555 break;
556 }
557
558 c = *p;
559 if(isspaceW(c)) {
560 while(isspaceW(*p))
561 p++;
562
563 if(cspace)
564 free_rangepoint(&last_space);
565 else
566 cspace = ' ';
567
568 iter->off = p-str;
569 c = *p;
570 nsAString_Finish(&nsstr);
571 if(!c) { /* continue to skip spaces */
572 init_rangepoint(&last_space, iter->node, iter->off);
573 break;
574 }
575
576 return cspace;
577 }else {
578 nsAString_Finish(&nsstr);
579 }
580
581 /* If we have a non-space char and we're skipping spaces, stop and return the last found space. */
582 if(cspace) {
583 free_rangepoint(iter);
584 *iter = last_space;
585 return cspace;
586 }
587
588 iter->off++;
589 return c;
590 }
591 case ELEMENT_NODE:
592 node = get_child_node(iter->node, iter->off);
593 if(!node)
594 break;
595
596 if(is_elem_tag(node, brW)) {
597 if(cspace) {
598 nsIDOMNode_Release(node);
599 free_rangepoint(iter);
600 *iter = last_space;
601 return cspace;
602 }
603
604 cspace = '\n';
605 init_rangepoint(&last_space, iter->node, iter->off+1);
606 }else if(is_elem_tag(node, hrW)) {
607 nsIDOMNode_Release(node);
608 if(cspace) {
609 free_rangepoint(iter);
610 *iter = last_space;
611 return cspace;
612 }
613
614 iter->off++;
615 return '\n';
616 }
617
618 nsIDOMNode_Release(node);
619 }
620 }while(rangepoint_next_node(iter));
621
622 return cspace;
623}
624
626{
627 rangepoint_t last_space;
629 WCHAR cspace = 0;
630 const WCHAR *p;
631
632 do {
633 switch(iter->type) {
634 case TEXT_NODE: {
635 const PRUnichar *str;
636 nsAString nsstr;
637 WCHAR c;
638
639 if(!iter->off)
640 break;
641
642 get_text_node_data(iter->node, &nsstr, &str);
643
644 p = str+iter->off-1;
645 c = *p;
646
647 if(isspaceW(c)) {
648 while(p > str && isspaceW(*(p-1)))
649 p--;
650
651 if(cspace)
652 free_rangepoint(&last_space);
653 else
654 cspace = ' ';
655
656 iter->off = p-str;
657 nsAString_Finish(&nsstr);
658 if(p == str) { /* continue to skip spaces */
659 init_rangepoint(&last_space, iter->node, iter->off);
660 break;
661 }
662
663 return cspace;
664 }else {
665 nsAString_Finish(&nsstr);
666 }
667
668 /* If we have a non-space char and we're skipping spaces, stop and return the last found space. */
669 if(cspace) {
670 free_rangepoint(iter);
671 *iter = last_space;
672 return cspace;
673 }
674
675 iter->off--;
676 return c;
677 }
678 case ELEMENT_NODE:
679 if(!iter->off)
680 break;
681
682 node = get_child_node(iter->node, iter->off-1);
683 if(!node)
684 break;
685
686 if(is_elem_tag(node, brW)) {
687 if(cspace)
688 free_rangepoint(&last_space);
689 cspace = '\n';
690 init_rangepoint(&last_space, iter->node, iter->off-1);
691 }else if(is_elem_tag(node, hrW)) {
692 nsIDOMNode_Release(node);
693 if(cspace) {
694 free_rangepoint(iter);
695 *iter = last_space;
696 return cspace;
697 }
698
699 iter->off--;
700 return '\n';
701 }
702
703 nsIDOMNode_Release(node);
704 }
705 }while(rangepoint_prev_node(iter));
706
707 if(cspace) {
708 free_rangepoint(iter);
709 *iter = last_space;
710 return cspace;
711 }
712
713 return 0;
714}
715
717{
718 LONG ret = 0;
719
720 if(cnt >= 0) {
721 while(ret < cnt && move_next_char(iter))
722 ret++;
723 }else {
724 while(ret > cnt && move_prev_char(iter))
725 ret--;
726 }
727
728 return ret;
729}
730
731static LONG find_prev_space(rangepoint_t *iter, BOOL first_space)
732{
733 rangepoint_t prev;
734 WCHAR c;
735
736 init_rangepoint(&prev, iter->node, iter->off);
737 c = move_prev_char(&prev);
738 if(!c || (first_space && isspaceW(c)))
739 return FALSE;
740
741 do {
742 free_rangepoint(iter);
743 init_rangepoint(iter, prev.node, prev.off);
744 c = move_prev_char(&prev);
745 }while(c && !isspaceW(c));
746
747 free_rangepoint(&prev);
748 return TRUE;
749}
750
751static BOOL find_word_end(rangepoint_t *iter, BOOL is_collapsed)
752{
753 rangepoint_t prev_iter;
754 WCHAR c;
755 BOOL ret = FALSE;
756
757 if(!is_collapsed) {
758 init_rangepoint(&prev_iter, iter->node, iter->off);
759 c = move_prev_char(&prev_iter);
760 free_rangepoint(&prev_iter);
761 if(isspaceW(c))
762 return FALSE;
763 }
764
765 do {
766 init_rangepoint(&prev_iter, iter->node, iter->off);
767 c = move_next_char(iter);
768 if(c == '\n') {
769 free_rangepoint(iter);
770 *iter = prev_iter;
771 return ret;
772 }
773 if(!c) {
774 if(!ret)
775 ret = !rangepoint_cmp(iter, &prev_iter);
776 }else {
777 ret = TRUE;
778 }
779 free_rangepoint(&prev_iter);
780 }while(c && !isspaceW(c));
781
782 return ret;
783}
784
786{
787 LONG ret = 0;
788
789 if(cnt >= 0) {
790 WCHAR c;
791
792 while(ret < cnt && (c = move_next_char(iter))) {
793 if(isspaceW(c))
794 ret++;
795 }
796 }else {
797 while(ret > cnt && find_prev_space(iter, FALSE))
798 ret--;
799 }
800
801 return ret;
802}
803
804static inline HTMLTxtRange *impl_from_IHTMLTxtRange(IHTMLTxtRange *iface)
805{
806 return CONTAINING_RECORD(iface, HTMLTxtRange, IHTMLTxtRange_iface);
807}
808
809static HRESULT WINAPI HTMLTxtRange_QueryInterface(IHTMLTxtRange *iface, REFIID riid, void **ppv)
810{
812
813 TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
814
816 *ppv = &This->IHTMLTxtRange_iface;
817 }else if(IsEqualGUID(&IID_IHTMLTxtRange, riid)) {
818 *ppv = &This->IHTMLTxtRange_iface;
819 }else if(IsEqualGUID(&IID_IOleCommandTarget, riid)) {
820 *ppv = &This->IOleCommandTarget_iface;
821 }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
822 return *ppv ? S_OK : E_NOINTERFACE;
823 }else {
824 *ppv = NULL;
825 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
826 return E_NOINTERFACE;
827 }
828
829 IUnknown_AddRef((IUnknown*)*ppv);
830 return S_OK;
831}
832
833static ULONG WINAPI HTMLTxtRange_AddRef(IHTMLTxtRange *iface)
834{
837
838 TRACE("(%p) ref=%d\n", This, ref);
839
840 return ref;
841}
842
843static ULONG WINAPI HTMLTxtRange_Release(IHTMLTxtRange *iface)
844{
847
848 TRACE("(%p) ref=%d\n", This, ref);
849
850 if(!ref) {
851 if(This->nsrange)
852 nsIDOMRange_Release(This->nsrange);
853 if(This->doc)
854 list_remove(&This->entry);
855 release_dispex(&This->dispex);
857 }
858
859 return ref;
860}
861
862static HRESULT WINAPI HTMLTxtRange_GetTypeInfoCount(IHTMLTxtRange *iface, UINT *pctinfo)
863{
865
866 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
867}
868
869static HRESULT WINAPI HTMLTxtRange_GetTypeInfo(IHTMLTxtRange *iface, UINT iTInfo,
870 LCID lcid, ITypeInfo **ppTInfo)
871{
873
874 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
875}
876
878 LPOLESTR *rgszNames, UINT cNames,
879 LCID lcid, DISPID *rgDispId)
880{
882
883 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames,
884 cNames, lcid, rgDispId);
885}
886
887static HRESULT WINAPI HTMLTxtRange_Invoke(IHTMLTxtRange *iface, DISPID dispIdMember,
888 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
889 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
890{
892
893 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid,
894 lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
895}
896
897static HRESULT WINAPI HTMLTxtRange_get_htmlText(IHTMLTxtRange *iface, BSTR *p)
898{
900
901 TRACE("(%p)->(%p)\n", This, p);
902
903 *p = NULL;
904
905 if(This->nsrange) {
906 nsIDOMDocumentFragment *fragment;
907 nsresult nsres;
908
909 nsres = nsIDOMRange_CloneContents(This->nsrange, &fragment);
910 if(NS_SUCCEEDED(nsres)) {
911 const PRUnichar *nstext;
912 nsAString nsstr;
913
914 nsAString_Init(&nsstr, NULL);
915 nsnode_to_nsstring((nsIDOMNode*)fragment, &nsstr);
916 nsIDOMDocumentFragment_Release(fragment);
917
918 nsAString_GetData(&nsstr, &nstext);
919 *p = SysAllocString(nstext);
920
921 nsAString_Finish(&nsstr);
922 }
923 }
924
925 if(!*p) {
926 const WCHAR emptyW[] = {0};
928 }
929
930 TRACE("return %s\n", debugstr_w(*p));
931 return S_OK;
932}
933
934static HRESULT WINAPI HTMLTxtRange_put_text(IHTMLTxtRange *iface, BSTR v)
935{
937 nsIDOMText *text_node;
938 nsAString text_str;
939 nsresult nsres;
940
941 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
942
943 if(!This->doc)
944 return MSHTML_E_NODOC;
945
946 nsAString_InitDepend(&text_str, v);
947 nsres = nsIDOMHTMLDocument_CreateTextNode(This->doc->nsdoc, &text_str, &text_node);
948 nsAString_Finish(&text_str);
949 if(NS_FAILED(nsres)) {
950 ERR("CreateTextNode failed: %08x\n", nsres);
951 return S_OK;
952 }
953 nsres = nsIDOMRange_DeleteContents(This->nsrange);
954 if(NS_FAILED(nsres))
955 ERR("DeleteContents failed: %08x\n", nsres);
956
957 nsres = nsIDOMRange_InsertNode(This->nsrange, (nsIDOMNode*)text_node);
958 if(NS_FAILED(nsres))
959 ERR("InsertNode failed: %08x\n", nsres);
960
961 nsres = nsIDOMRange_SetEndAfter(This->nsrange, (nsIDOMNode*)text_node);
962 if(NS_FAILED(nsres))
963 ERR("SetEndAfter failed: %08x\n", nsres);
964
965 return IHTMLTxtRange_collapse(&This->IHTMLTxtRange_iface, VARIANT_FALSE);
966}
967
968static HRESULT WINAPI HTMLTxtRange_get_text(IHTMLTxtRange *iface, BSTR *p)
969{
972
973 TRACE("(%p)->(%p)\n", This, p);
974
975 *p = NULL;
976 if(!This->nsrange)
977 return S_OK;
978
979 if (!wstrbuf_init(&buf))
980 return E_OUTOFMEMORY;
982 if (buf.buf)
983 *p = SysAllocString(buf.buf);
985
986 TRACE("ret %s\n", debugstr_w(*p));
987 return S_OK;
988}
989
990static HRESULT WINAPI HTMLTxtRange_parentElement(IHTMLTxtRange *iface, IHTMLElement **parent)
991{
993 nsIDOMNode *nsnode, *tmp;
996
997 TRACE("(%p)->(%p)\n", This, parent);
998
999 nsIDOMRange_GetCommonAncestorContainer(This->nsrange, &nsnode);
1000 while(nsnode && get_node_type(nsnode) != ELEMENT_NODE) {
1001 nsIDOMNode_GetParentNode(nsnode, &tmp);
1002 nsIDOMNode_Release(nsnode);
1003 nsnode = tmp;
1004 }
1005
1006 if(!nsnode) {
1007 *parent = NULL;
1008 return S_OK;
1009 }
1010
1011 hres = get_node(This->doc, nsnode, TRUE, &node);
1012 nsIDOMNode_Release(nsnode);
1013 if(FAILED(hres))
1014 return hres;
1015
1016 hres = IHTMLDOMNode_QueryInterface(&node->IHTMLDOMNode_iface, &IID_IHTMLElement, (void**)parent);
1018 return hres;
1019}
1020
1021static HRESULT WINAPI HTMLTxtRange_duplicate(IHTMLTxtRange *iface, IHTMLTxtRange **Duplicate)
1022{
1024 nsIDOMRange *nsrange = NULL;
1025 HRESULT hres;
1026
1027 TRACE("(%p)->(%p)\n", This, Duplicate);
1028
1029 nsIDOMRange_CloneRange(This->nsrange, &nsrange);
1030 hres = HTMLTxtRange_Create(This->doc, nsrange, Duplicate);
1031 nsIDOMRange_Release(nsrange);
1032
1033 return hres;
1034}
1035
1036static HRESULT WINAPI HTMLTxtRange_inRange(IHTMLTxtRange *iface, IHTMLTxtRange *Range,
1037 VARIANT_BOOL *InRange)
1038{
1040 HTMLTxtRange *src_range;
1041 short nsret = 0;
1042 nsresult nsres;
1043
1044 TRACE("(%p)->(%p %p)\n", This, Range, InRange);
1045
1046 *InRange = VARIANT_FALSE;
1047
1048 src_range = get_range_object(This->doc, Range);
1049 if(!src_range)
1050 return E_FAIL;
1051
1052 nsres = nsIDOMRange_CompareBoundaryPoints(This->nsrange, NS_START_TO_START,
1053 src_range->nsrange, &nsret);
1054 if(NS_SUCCEEDED(nsres) && nsret <= 0) {
1055 nsres = nsIDOMRange_CompareBoundaryPoints(This->nsrange, NS_END_TO_END,
1056 src_range->nsrange, &nsret);
1057 if(NS_SUCCEEDED(nsres) && nsret >= 0)
1058 *InRange = VARIANT_TRUE;
1059 }
1060
1061 if(NS_FAILED(nsres))
1062 ERR("CompareBoundaryPoints failed: %08x\n", nsres);
1063
1064 return S_OK;
1065}
1066
1067static HRESULT WINAPI HTMLTxtRange_isEqual(IHTMLTxtRange *iface, IHTMLTxtRange *Range,
1069{
1071 HTMLTxtRange *src_range;
1072 short nsret = 0;
1073 nsresult nsres;
1074
1075 TRACE("(%p)->(%p %p)\n", This, Range, IsEqual);
1076
1077 *IsEqual = VARIANT_FALSE;
1078
1079 src_range = get_range_object(This->doc, Range);
1080 if(!src_range)
1081 return E_FAIL;
1082
1083 nsres = nsIDOMRange_CompareBoundaryPoints(This->nsrange, NS_START_TO_START,
1084 src_range->nsrange, &nsret);
1085 if(NS_SUCCEEDED(nsres) && !nsret) {
1086 nsres = nsIDOMRange_CompareBoundaryPoints(This->nsrange, NS_END_TO_END,
1087 src_range->nsrange, &nsret);
1088 if(NS_SUCCEEDED(nsres) && !nsret)
1089 *IsEqual = VARIANT_TRUE;
1090 }
1091
1092 if(NS_FAILED(nsres))
1093 ERR("CompareBoundaryPoints failed: %08x\n", nsres);
1094
1095 return S_OK;
1096}
1097
1098static HRESULT WINAPI HTMLTxtRange_scrollIntoView(IHTMLTxtRange *iface, VARIANT_BOOL fStart)
1099{
1101 FIXME("(%p)->(%x)\n", This, fStart);
1102 return E_NOTIMPL;
1103}
1104
1106{
1108
1109 TRACE("(%p)->(%x)\n", This, Start);
1110
1111 nsIDOMRange_Collapse(This->nsrange, Start != VARIANT_FALSE);
1112 return S_OK;
1113}
1114
1116{
1119
1120 TRACE("(%p)->(%s %p)\n", This, debugstr_w(Unit), Success);
1121
1123 if(unit == RU_UNKNOWN)
1124 return E_INVALIDARG;
1125
1126 *Success = VARIANT_FALSE;
1127
1128 switch(unit) {
1129 case RU_WORD: {
1131 cpp_bool is_collapsed;
1132
1135
1136 nsIDOMRange_GetCollapsed(This->nsrange, &is_collapsed);
1137
1138 if(find_word_end(&end, is_collapsed)) {
1140 *Success = VARIANT_TRUE;
1141 }
1142
1143 if(find_prev_space(&start, TRUE)) {
1145 *Success = VARIANT_TRUE;
1146 }
1147
1150 break;
1151 }
1152
1153 case RU_TEXTEDIT: {
1154 nsIDOMHTMLElement *nsbody = NULL;
1155 nsresult nsres;
1156
1157 nsres = nsIDOMHTMLDocument_GetBody(This->doc->nsdoc, &nsbody);
1158 if(NS_FAILED(nsres) || !nsbody) {
1159 ERR("Could not get body: %08x\n", nsres);
1160 break;
1161 }
1162
1163 nsres = nsIDOMRange_SelectNodeContents(This->nsrange, (nsIDOMNode*)nsbody);
1164 nsIDOMHTMLElement_Release(nsbody);
1165 if(NS_FAILED(nsres)) {
1166 ERR("Collapse failed: %08x\n", nsres);
1167 break;
1168 }
1169
1170 *Success = VARIANT_TRUE;
1171 break;
1172 }
1173
1174 default:
1175 FIXME("Unimplemented unit %s\n", debugstr_w(Unit));
1176 }
1177
1178 return S_OK;
1179}
1180
1181static HRESULT WINAPI HTMLTxtRange_move(IHTMLTxtRange *iface, BSTR Unit,
1182 LONG Count, LONG *ActualCount)
1183{
1186
1187 TRACE("(%p)->(%s %d %p)\n", This, debugstr_w(Unit), Count, ActualCount);
1188
1190 if(unit == RU_UNKNOWN)
1191 return E_INVALIDARG;
1192
1193 if(!Count) {
1194 *ActualCount = 0;
1195 return IHTMLTxtRange_collapse(&This->IHTMLTxtRange_iface, VARIANT_TRUE);
1196 }
1197
1198 switch(unit) {
1199 case RU_CHAR: {
1201
1203
1204 *ActualCount = move_by_chars(&start, Count);
1205
1207 IHTMLTxtRange_collapse(&This->IHTMLTxtRange_iface, VARIANT_TRUE);
1209 break;
1210 }
1211
1212 case RU_WORD: {
1214
1216
1217 *ActualCount = move_by_words(&start, Count);
1218
1220 IHTMLTxtRange_collapse(&This->IHTMLTxtRange_iface, VARIANT_TRUE);
1222 break;
1223 }
1224
1225 default:
1226 FIXME("unimplemented unit %s\n", debugstr_w(Unit));
1227 }
1228
1229 TRACE("ret %d\n", *ActualCount);
1230 return S_OK;
1231}
1232
1233static HRESULT WINAPI HTMLTxtRange_moveStart(IHTMLTxtRange *iface, BSTR Unit,
1234 LONG Count, LONG *ActualCount)
1235{
1238
1239 TRACE("(%p)->(%s %d %p)\n", This, debugstr_w(Unit), Count, ActualCount);
1240
1242 if(unit == RU_UNKNOWN)
1243 return E_INVALIDARG;
1244
1245 if(!Count) {
1246 *ActualCount = 0;
1247 return S_OK;
1248 }
1249
1250 switch(unit) {
1251 case RU_CHAR: {
1253
1255
1256 *ActualCount = move_by_chars(&start, Count);
1257
1260 break;
1261 }
1262
1263 default:
1264 FIXME("unimplemented unit %s\n", debugstr_w(Unit));
1265 return E_NOTIMPL;
1266 }
1267
1268 return S_OK;
1269}
1270
1271static HRESULT WINAPI HTMLTxtRange_moveEnd(IHTMLTxtRange *iface, BSTR Unit,
1272 LONG Count, LONG *ActualCount)
1273{
1276
1277 TRACE("(%p)->(%s %d %p)\n", This, debugstr_w(Unit), Count, ActualCount);
1278
1280 if(unit == RU_UNKNOWN)
1281 return E_INVALIDARG;
1282
1283 if(!Count) {
1284 *ActualCount = 0;
1285 return S_OK;
1286 }
1287
1288 switch(unit) {
1289 case RU_CHAR: {
1291
1293
1294 *ActualCount = move_by_chars(&end, Count);
1295
1298 break;
1299 }
1300
1301 default:
1302 FIXME("unimplemented unit %s\n", debugstr_w(Unit));
1303 }
1304
1305 return S_OK;
1306}
1307
1308static HRESULT WINAPI HTMLTxtRange_select(IHTMLTxtRange *iface)
1309{
1311 nsISelection *nsselection;
1312 nsresult nsres;
1313
1314 TRACE("(%p)\n", This);
1315
1316 nsres = nsIDOMWindow_GetSelection(This->doc->basedoc.window->nswindow, &nsselection);
1317 if(NS_FAILED(nsres)) {
1318 ERR("GetSelection failed: %08x\n", nsres);
1319 return E_FAIL;
1320 }
1321
1322 nsISelection_RemoveAllRanges(nsselection);
1323 nsISelection_AddRange(nsselection, This->nsrange);
1324 nsISelection_Release(nsselection);
1325 return S_OK;
1326}
1327
1328static HRESULT WINAPI HTMLTxtRange_pasteHTML(IHTMLTxtRange *iface, BSTR html)
1329{
1331 nsIDOMDocumentFragment *doc_frag;
1332 nsAString nsstr;
1333 nsresult nsres;
1334
1335 TRACE("(%p)->(%s)\n", This, debugstr_w(html));
1336
1337 nsres = nsIDOMRange_Collapse(This->nsrange, TRUE);
1338 assert(nsres == NS_OK);
1339
1340 nsAString_InitDepend(&nsstr, html);
1341 nsres = nsIDOMRange_CreateContextualFragment(This->nsrange, &nsstr, &doc_frag);
1342 nsAString_Finish(&nsstr);
1343 if(NS_FAILED(nsres)) {
1344 ERR("CreateContextualFragment failed: %08x\n", nsres);
1345 return E_FAIL;
1346 }
1347
1348 nsres = nsIDOMRange_InsertNode(This->nsrange, (nsIDOMNode*)doc_frag);
1349 nsIDOMDocumentFragment_Release(doc_frag);
1350 if(NS_FAILED(nsres)) {
1351 ERR("InsertNode failed: %08x\n", nsres);
1352 return E_FAIL;
1353 }
1354
1355 nsres = nsIDOMRange_Collapse(This->nsrange, FALSE);
1356 assert(nsres == NS_OK);
1357 return S_OK;
1358}
1359
1360static HRESULT WINAPI HTMLTxtRange_moveToElementText(IHTMLTxtRange *iface, IHTMLElement *element)
1361{
1364 nsresult nsres;
1365
1366 TRACE("(%p)->(%p)\n", This, element);
1367
1369 if(!elem)
1370 return E_INVALIDARG;
1371
1372 nsres = nsIDOMRange_SelectNodeContents(This->nsrange, elem->node.nsnode);
1373 if(NS_FAILED(nsres)) {
1374 ERR("SelectNodeContents failed: %08x\n", nsres);
1375 return E_FAIL;
1376 }
1377
1378 return S_OK;
1379}
1380
1381static HRESULT WINAPI HTMLTxtRange_setEndPoint(IHTMLTxtRange *iface, BSTR how,
1382 IHTMLTxtRange *SourceRange)
1383{
1385 HTMLTxtRange *src_range;
1386 nsIDOMNode *ref_node;
1387 INT32 ref_offset;
1388 BOOL set_start;
1389 int how_type;
1390 INT16 cmp;
1391 nsresult nsres;
1392
1393 TRACE("(%p)->(%s %p)\n", This, debugstr_w(how), SourceRange);
1394
1395 how_type = string_to_nscmptype(how);
1396 if(how_type == -1)
1397 return E_INVALIDARG;
1398
1399 src_range = get_range_object(This->doc, SourceRange);
1400 if(!src_range)
1401 return E_FAIL;
1402
1403 switch(how_type) {
1404 case NS_START_TO_START:
1405 case NS_END_TO_START:
1406 nsres = nsIDOMRange_GetStartContainer(src_range->nsrange, &ref_node);
1407 assert(nsres == NS_OK);
1408
1409 nsres = nsIDOMRange_GetStartOffset(src_range->nsrange, &ref_offset);
1410 assert(nsres == NS_OK);
1411
1412 set_start = how_type == NS_START_TO_START;
1413 break;
1414 case NS_END_TO_END:
1415 case NS_START_TO_END:
1416 nsres = nsIDOMRange_GetEndContainer(src_range->nsrange, &ref_node);
1417 assert(nsres == NS_OK);
1418
1419 nsres = nsIDOMRange_GetEndOffset(src_range->nsrange, &ref_offset);
1420 assert(nsres == NS_OK);
1421
1422 set_start = how_type == NS_START_TO_END;
1423 break;
1425 }
1426
1427 nsres = nsIDOMRange_ComparePoint(This->nsrange, ref_node, ref_offset, &cmp);
1428 assert(nsres == NS_OK);
1429
1430 if(set_start) {
1431 if(cmp <= 0) {
1432 nsres = nsIDOMRange_SetStart(This->nsrange, ref_node, ref_offset);
1433 }else {
1434 nsres = nsIDOMRange_Collapse(This->nsrange, FALSE);
1435 assert(nsres == NS_OK);
1436
1437 nsres = nsIDOMRange_SetEnd(This->nsrange, ref_node, ref_offset);
1438 }
1439 }else {
1440 if(cmp >= 0) {
1441 nsres = nsIDOMRange_SetEnd(This->nsrange, ref_node, ref_offset);
1442 }else {
1443 nsres = nsIDOMRange_Collapse(This->nsrange, TRUE);
1444 assert(nsres == NS_OK);
1445
1446 nsres = nsIDOMRange_SetStart(This->nsrange, ref_node, ref_offset);
1447 }
1448 }
1449 assert(nsres == NS_OK);
1450
1451 nsIDOMNode_Release(ref_node);
1452 return S_OK;
1453}
1454
1455static HRESULT WINAPI HTMLTxtRange_compareEndPoints(IHTMLTxtRange *iface, BSTR how,
1456 IHTMLTxtRange *SourceRange, LONG *ret)
1457{
1459 HTMLTxtRange *src_range;
1460 short nsret = 0;
1461 int nscmpt;
1462 nsresult nsres;
1463
1464 TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(how), SourceRange, ret);
1465
1466 nscmpt = string_to_nscmptype(how);
1467 if(nscmpt == -1)
1468 return E_INVALIDARG;
1469
1470 src_range = get_range_object(This->doc, SourceRange);
1471 if(!src_range)
1472 return E_FAIL;
1473
1474 nsres = nsIDOMRange_CompareBoundaryPoints(This->nsrange, nscmpt, src_range->nsrange, &nsret);
1475 if(NS_FAILED(nsres))
1476 ERR("CompareBoundaryPoints failed: %08x\n", nsres);
1477
1478 *ret = nsret;
1479 return S_OK;
1480}
1481
1482static HRESULT WINAPI HTMLTxtRange_findText(IHTMLTxtRange *iface, BSTR String,
1484{
1486 FIXME("(%p)->(%s %d %08x %p)\n", This, debugstr_w(String), count, Flags, Success);
1487 return E_NOTIMPL;
1488}
1489
1490static HRESULT WINAPI HTMLTxtRange_moveToPoint(IHTMLTxtRange *iface, LONG x, LONG y)
1491{
1493 FIXME("(%p)->(%d %d)\n", This, x, y);
1494 return E_NOTIMPL;
1495}
1496
1498{
1500 FIXME("(%p)->(%p)\n", This, Bookmark);
1501 return E_NOTIMPL;
1502}
1503
1506{
1508 FIXME("(%p)->(%s %p)\n", This, debugstr_w(Bookmark), Success);
1509 return E_NOTIMPL;
1510}
1511
1512static HRESULT WINAPI HTMLTxtRange_queryCommandSupported(IHTMLTxtRange *iface, BSTR cmdID,
1513 VARIANT_BOOL *pfRet)
1514{
1516 FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
1517 return E_NOTIMPL;
1518}
1519
1520static HRESULT WINAPI HTMLTxtRange_queryCommandEnabled(IHTMLTxtRange *iface, BSTR cmdID,
1521 VARIANT_BOOL *pfRet)
1522{
1524 FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
1525 return E_NOTIMPL;
1526}
1527
1528static HRESULT WINAPI HTMLTxtRange_queryCommandState(IHTMLTxtRange *iface, BSTR cmdID,
1529 VARIANT_BOOL *pfRet)
1530{
1532 FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
1533 return E_NOTIMPL;
1534}
1535
1536static HRESULT WINAPI HTMLTxtRange_queryCommandIndeterm(IHTMLTxtRange *iface, BSTR cmdID,
1537 VARIANT_BOOL *pfRet)
1538{
1540 FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
1541 return E_NOTIMPL;
1542}
1543
1544static HRESULT WINAPI HTMLTxtRange_queryCommandText(IHTMLTxtRange *iface, BSTR cmdID,
1545 BSTR *pcmdText)
1546{
1548 FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pcmdText);
1549 return E_NOTIMPL;
1550}
1551
1552static HRESULT WINAPI HTMLTxtRange_queryCommandValue(IHTMLTxtRange *iface, BSTR cmdID,
1553 VARIANT *pcmdValue)
1554{
1556 FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pcmdValue);
1557 return E_NOTIMPL;
1558}
1559
1560static HRESULT WINAPI HTMLTxtRange_execCommand(IHTMLTxtRange *iface, BSTR cmdID,
1561 VARIANT_BOOL showUI, VARIANT value, VARIANT_BOOL *pfRet)
1562{
1564 FIXME("(%p)->(%s %x v %p)\n", This, debugstr_w(cmdID), showUI, pfRet);
1565 return E_NOTIMPL;
1566}
1567
1568static HRESULT WINAPI HTMLTxtRange_execCommandShowHelp(IHTMLTxtRange *iface, BSTR cmdID,
1569 VARIANT_BOOL *pfRet)
1570{
1572 FIXME("(%p)->(%s %p)\n", This, debugstr_w(cmdID), pfRet);
1573 return E_NOTIMPL;
1574}
1575
1576static const IHTMLTxtRangeVtbl HTMLTxtRangeVtbl = {
1614};
1615
1617{
1618 return CONTAINING_RECORD(iface, HTMLTxtRange, IOleCommandTarget_iface);
1619}
1620
1622{
1624 return IHTMLTxtRange_QueryInterface(&This->IHTMLTxtRange_iface, riid, ppv);
1625}
1626
1628{
1630 return IHTMLTxtRange_AddRef(&This->IHTMLTxtRange_iface);
1631}
1632
1634{
1636 return IHTMLTxtRange_Release(&This->IHTMLTxtRange_iface);
1637}
1638
1640 ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText)
1641{
1643 FIXME("(%p)->(%s %d %p %p)\n", This, debugstr_guid(pguidCmdGroup), cCmds, prgCmds, pCmdText);
1644 return E_NOTIMPL;
1645}
1646
1648{
1649 nsIDOMHTMLElement *blockquote_elem, *p_elem;
1650 nsIDOMDocumentFragment *fragment;
1651 nsIDOMNode *tmp;
1652
1653 static const PRUnichar blockquoteW[] = {'B','L','O','C','K','Q','U','O','T','E',0};
1654 static const PRUnichar pW[] = {'P',0};
1655
1656 TRACE("(%p)->(%p %p)\n", This, in, out);
1657
1658 if(!This->doc->nsdoc) {
1659 WARN("NULL nsdoc\n");
1660 return E_NOTIMPL;
1661 }
1662
1663 create_nselem(This->doc, blockquoteW, &blockquote_elem);
1664 create_nselem(This->doc, pW, &p_elem);
1665
1666 nsIDOMRange_ExtractContents(This->nsrange, &fragment);
1667 nsIDOMHTMLElement_AppendChild(p_elem, (nsIDOMNode*)fragment, &tmp);
1668 nsIDOMDocumentFragment_Release(fragment);
1669 nsIDOMNode_Release(tmp);
1670
1671 nsIDOMHTMLElement_AppendChild(blockquote_elem, (nsIDOMNode*)p_elem, &tmp);
1672 nsIDOMHTMLElement_Release(p_elem);
1673 nsIDOMNode_Release(tmp);
1674
1675 nsIDOMRange_InsertNode(This->nsrange, (nsIDOMNode*)blockquote_elem);
1676 nsIDOMHTMLElement_Release(blockquote_elem);
1677
1678 return S_OK;
1679}
1680
1682 DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
1683{
1685
1686 TRACE("(%p)->(%s %d %x %p %p)\n", This, debugstr_guid(pguidCmdGroup), nCmdID,
1687 nCmdexecopt, pvaIn, pvaOut);
1688
1689 if(pguidCmdGroup && IsEqualGUID(&CGID_MSHTML, pguidCmdGroup)) {
1690 switch(nCmdID) {
1691 case IDM_INDENT:
1692 return exec_indent(This, pvaIn, pvaOut);
1693 default:
1694 FIXME("Unsupported cmdid %d of CGID_MSHTML\n", nCmdID);
1695 }
1696 }else {
1697 FIXME("Unsupported cmd %d of group %s\n", nCmdID, debugstr_guid(pguidCmdGroup));
1698 }
1699
1700 return E_NOTIMPL;
1701}
1702
1703static const IOleCommandTargetVtbl OleCommandTargetVtbl = {
1709};
1710
1712 IHTMLTxtRange_tid,
1713 0
1714};
1716 NULL,
1717 IHTMLTxtRange_tid,
1718 NULL,
1720};
1721
1723{
1725
1726 ret = heap_alloc(sizeof(HTMLTxtRange));
1727 if(!ret)
1728 return E_OUTOFMEMORY;
1729
1730 init_dispex(&ret->dispex, (IUnknown*)&ret->IHTMLTxtRange_iface, &HTMLTxtRange_dispex);
1731
1732 ret->IHTMLTxtRange_iface.lpVtbl = &HTMLTxtRangeVtbl;
1733 ret->IOleCommandTarget_iface.lpVtbl = &OleCommandTargetVtbl;
1734 ret->ref = 1;
1735
1736 if(nsrange)
1737 nsIDOMRange_AddRef(nsrange);
1738 ret->nsrange = nsrange;
1739
1740 ret->doc = doc;
1741 list_add_head(&doc->range_list, &ret->entry);
1742
1743 *p = &ret->IHTMLTxtRange_iface;
1744 return S_OK;
1745}
1746
1748{
1749 HTMLTxtRange *iter;
1750
1751 LIST_FOR_EACH_ENTRY(iter, &This->range_list, HTMLTxtRange, entry) {
1752 iter->doc = NULL;
1753 }
1754}
unsigned short UINT16
signed int INT32
signed short INT16
unsigned int UINT32
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
const GUID IID_IUnknown
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
Definition: list.h:37
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned char cpp_bool
Definition: atl.c:38
OLECHAR * BSTR
Definition: compat.h:2293
short VARIANT_BOOL
Definition: compat.h:2290
const char * debugstr_mshtml_guid(const GUID *iid)
Definition: main.c:542
#define assert(x)
Definition: debug.h:53
static WCHAR characterW[]
Definition: dom.c:79
#define get_node_type(n)
Definition: dom.c:1111
static WCHAR texteditW[]
Definition: dom.c:80
static WCHAR wordW[]
Definition: dom.c:81
r parent
Definition: btrfs.c:3010
@ Success
Definition: eventcreate.c:712
@ IsEqual
Definition: fatprocs.h:1886
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
Unit
Definition: gdiplusenums.h:26
GLuint start
Definition: gl.h:1545
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
const GLdouble * v
Definition: gl.h:2040
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
const GLubyte * c
Definition: glext.h:8905
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint in
Definition: glext.h:9616
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
HTMLElement * unsafe_impl_from_IHTMLElement(IHTMLElement *iface)
Definition: htmlelem.c:1962
HRESULT create_nselem(HTMLDocumentNode *doc, const WCHAR *tag, nsIDOMHTMLElement **ret)
Definition: htmlelem.c:246
HRESULT get_node(HTMLDocumentNode *This, nsIDOMNode *nsnode, BOOL create, HTMLDOMNode **ret)
Definition: htmlnode.c:1339
static const WCHAR emptyW[]
Definition: navigate.c:40
tid_t
Definition: ieframe.h:311
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
uint32_t entry
Definition: isohybrid.c:63
HRESULT init_dispex(jsdisp_t *dispex, script_ctx_t *ctx, const builtin_info_t *builtin_info, jsdisp_t *prototype)
Definition: dispex.c:919
#define d
Definition: ke_i.h:81
#define c
Definition: ke_i.h:80
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_wn
Definition: kernel32.h:33
#define debugstr_w
Definition: kernel32.h:32
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
HRESULT hres
Definition: protocol.c:465
static size_t elem
Definition: string.c:68
#define cmp(status, error)
Definition: error.c:114
static LPOLESTR
Definition: stg_prop.c:27
static VARIANTARG static DISPID
Definition: ordinal.c:52
static HWND child
Definition: cursoricon.c:298
#define IDM_INDENT
Definition: mshtmcid.h:207
void release_dispex(DispatchEx *This)
Definition: dispex.c:1706
BOOL dispex_query_interface(DispatchEx *This, REFIID riid, void **ppv)
Definition: dispex.c:1656
#define NS_OK
HRESULT nsnode_to_nsstring(nsIDOMNode *, nsAString *) DECLSPEC_HIDDEN
Definition: nsembed.c:1000
void nsAString_Finish(nsAString *) DECLSPEC_HIDDEN
Definition: nsembed.c:836
UINT32 nsAString_GetData(const nsAString *, const PRUnichar **) DECLSPEC_HIDDEN
Definition: nsembed.c:831
#define MSHTML_E_NODOC
void nsAString_InitDepend(nsAString *, const PRUnichar *) DECLSPEC_HIDDEN
Definition: nsembed.c:826
BOOL nsAString_Init(nsAString *, const PRUnichar *) DECLSPEC_HIDDEN
Definition: nsembed.c:817
static void node_release(HTMLDOMNode *node)
#define NS_SUCCEEDED(res)
#define NS_FAILED(res)
unsigned int UINT
Definition: ndis.h:50
int Count
Definition: noreturn.cpp:7
WCHAR PRUnichar
Definition: nsiface.idl:48
#define DEFAULT_UNREACHABLE
BSTR WINAPI SysAllocString(LPCOLESTR str)
Definition: oleaut.c:238
long LONG
Definition: pedump.c:60
png_const_structrp png_const_inforp int * unit
Definition: png.h:2159
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define REFIID
Definition: guiddef.h:118
#define strchrW(s, c)
Definition: unicode.h:34
#define strcmpiW(s1, s2)
Definition: unicode.h:39
#define strlenW(s)
Definition: unicode.h:28
#define isspaceW(n)
Definition: unicode.h:52
static FILE * out
Definition: regtests2xml.c:44
const WCHAR * str
DWORD LCID
Definition: nls.h:13
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define TRACE(s)
Definition: solgame.cpp:4
struct list range_list
IOleCommandTarget IOleCommandTarget_iface
Definition: txtrange.c:27
HTMLDocumentNode * doc
Definition: txtrange.c:32
LONG ref
Definition: txtrange.c:29
DispatchEx dispex
Definition: txtrange.c:25
IHTMLTxtRange IHTMLTxtRange_iface
Definition: txtrange.c:26
nsIDOMRange * nsrange
Definition: txtrange.c:31
UINT16 type
Definition: txtrange.c:44
UINT32 off
Definition: txtrange.c:46
nsIDOMNode * node
Definition: txtrange.c:45
Definition: send.c:48
Definition: range.c:39
Definition: ecma_167.h:138
DWORD size
Definition: txtrange.c:40
DWORD len
Definition: txtrange.c:39
WCHAR * buf
Definition: txtrange.c:38
static nsIDOMNode * get_child_node(nsIDOMNode *node, UINT32 off)
Definition: txtrange.c:131
static HRESULT WINAPI HTMLTxtRange_moveEnd(IHTMLTxtRange *iface, BSTR Unit, LONG Count, LONG *ActualCount)
Definition: txtrange.c:1271
static void wstrbuf_append_node(wstrbuf_t *buf, nsIDOMNode *node, BOOL ignore_text)
Definition: txtrange.c:404
static BOOL wstrbuf_init(wstrbuf_t *buf)
Definition: txtrange.c:344
static BOOL find_word_end(rangepoint_t *iter, BOOL is_collapsed)
Definition: txtrange.c:751
static HRESULT WINAPI HTMLTxtRange_get_text(IHTMLTxtRange *iface, BSTR *p)
Definition: txtrange.c:968
static HRESULT WINAPI RangeCommandTarget_Exec(IOleCommandTarget *iface, const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
Definition: txtrange.c:1681
static void get_text_node_data(nsIDOMNode *node, nsAString *nsstr, const PRUnichar **str)
Definition: txtrange.c:114
static HRESULT WINAPI HTMLTxtRange_move(IHTMLTxtRange *iface, BSTR Unit, LONG Count, LONG *ActualCount)
Definition: txtrange.c:1181
static ULONG WINAPI HTMLTxtRange_AddRef(IHTMLTxtRange *iface)
Definition: txtrange.c:833
static range_unit_t string_to_unit(LPCWSTR str)
Definition: txtrange.c:70
static int get_child_index(nsIDOMNode *parent, nsIDOMNode *child)
Definition: txtrange.c:146
static WCHAR move_next_char(rangepoint_t *iter)
Definition: txtrange.c:537
static HTMLTxtRange * get_range_object(HTMLDocumentNode *doc, IHTMLTxtRange *iface)
Definition: txtrange.c:57
static void wstrbuf_finish(wstrbuf_t *buf)
Definition: txtrange.c:354
static HRESULT WINAPI HTMLTxtRange_queryCommandIndeterm(IHTMLTxtRange *iface, BSTR cmdID, VARIANT_BOOL *pfRet)
Definition: txtrange.c:1536
static HRESULT WINAPI HTMLTxtRange_parentElement(IHTMLTxtRange *iface, IHTMLElement **parent)
Definition: txtrange.c:990
static BOOL rangepoint_cmp(const rangepoint_t *point1, const rangepoint_t *point2)
Definition: txtrange.c:185
static HRESULT WINAPI HTMLTxtRange_pasteHTML(IHTMLTxtRange *iface, BSTR html)
Definition: txtrange.c:1328
static void range_to_string(HTMLTxtRange *This, wstrbuf_t *buf)
Definition: txtrange.c:454
static const IHTMLTxtRangeVtbl HTMLTxtRangeVtbl
Definition: txtrange.c:1576
static HRESULT WINAPI HTMLTxtRange_moveToElementText(IHTMLTxtRange *iface, IHTMLElement *element)
Definition: txtrange.c:1360
static void free_rangepoint(rangepoint_t *rangepoint)
Definition: txtrange.c:180
static HRESULT WINAPI HTMLTxtRange_execCommandShowHelp(IHTMLTxtRange *iface, BSTR cmdID, VARIANT_BOOL *pfRet)
Definition: txtrange.c:1568
static HRESULT WINAPI HTMLTxtRange_setEndPoint(IHTMLTxtRange *iface, BSTR how, IHTMLTxtRange *SourceRange)
Definition: txtrange.c:1381
static HRESULT WINAPI HTMLTxtRange_moveToPoint(IHTMLTxtRange *iface, LONG x, LONG y)
Definition: txtrange.c:1490
static int string_to_nscmptype(LPCWSTR str)
Definition: txtrange.c:89
static HRESULT WINAPI HTMLTxtRange_moveStart(IHTMLTxtRange *iface, BSTR Unit, LONG Count, LONG *ActualCount)
Definition: txtrange.c:1233
static HRESULT WINAPI HTMLTxtRange_get_htmlText(IHTMLTxtRange *iface, BSTR *p)
Definition: txtrange.c:897
static HRESULT WINAPI HTMLTxtRange_execCommand(IHTMLTxtRange *iface, BSTR cmdID, VARIANT_BOOL showUI, VARIANT value, VARIANT_BOOL *pfRet)
Definition: txtrange.c:1560
HRESULT HTMLTxtRange_Create(HTMLDocumentNode *doc, nsIDOMRange *nsrange, IHTMLTxtRange **p)
Definition: txtrange.c:1722
static WCHAR move_prev_char(rangepoint_t *iter)
Definition: txtrange.c:625
static void wstrbuf_append_nodetxt(wstrbuf_t *buf, LPCWSTR str, int len)
Definition: txtrange.c:371
static HRESULT exec_indent(HTMLTxtRange *This, VARIANT *in, VARIANT *out)
Definition: txtrange.c:1647
static LONG move_by_words(rangepoint_t *iter, LONG cnt)
Definition: txtrange.c:785
static HRESULT WINAPI HTMLTxtRange_expand(IHTMLTxtRange *iface, BSTR Unit, VARIANT_BOOL *Success)
Definition: txtrange.c:1115
static ULONG WINAPI RangeCommandTarget_Release(IOleCommandTarget *iface)
Definition: txtrange.c:1633
static HRESULT WINAPI HTMLTxtRange_moveToBookmark(IHTMLTxtRange *iface, BSTR Bookmark, VARIANT_BOOL *Success)
Definition: txtrange.c:1504
static HRESULT WINAPI HTMLTxtRange_scrollIntoView(IHTMLTxtRange *iface, VARIANT_BOOL fStart)
Definition: txtrange.c:1098
HRESULT get_node_text(HTMLDOMNode *node, BSTR *ret)
Definition: txtrange.c:515
static void get_end_point(HTMLTxtRange *This, rangepoint_t *ret)
Definition: txtrange.c:293
static UINT32 get_text_length(nsIDOMNode *node)
Definition: txtrange.c:234
range_unit_t
Definition: txtrange.c:49
@ RU_UNKNOWN
Definition: txtrange.c:50
@ RU_WORD
Definition: txtrange.c:52
@ RU_TEXTEDIT
Definition: txtrange.c:54
@ RU_SENTENCE
Definition: txtrange.c:53
@ RU_CHAR
Definition: txtrange.c:51
static LONG move_by_chars(rangepoint_t *iter, LONG cnt)
Definition: txtrange.c:716
static HRESULT WINAPI HTMLTxtRange_collapse(IHTMLTxtRange *iface, VARIANT_BOOL Start)
Definition: txtrange.c:1105
static ULONG WINAPI HTMLTxtRange_Release(IHTMLTxtRange *iface)
Definition: txtrange.c:843
static void set_end_point(HTMLTxtRange *This, const rangepoint_t *end)
Definition: txtrange.c:313
static HRESULT WINAPI HTMLTxtRange_GetTypeInfoCount(IHTMLTxtRange *iface, UINT *pctinfo)
Definition: txtrange.c:862
static HRESULT WINAPI RangeCommandTarget_QueryStatus(IOleCommandTarget *iface, const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText)
Definition: txtrange.c:1639
static HRESULT WINAPI HTMLTxtRange_put_text(IHTMLTxtRange *iface, BSTR v)
Definition: txtrange.c:934
void detach_ranges(HTMLDocumentNode *This)
Definition: txtrange.c:1747
static HRESULT WINAPI HTMLTxtRange_queryCommandValue(IHTMLTxtRange *iface, BSTR cmdID, VARIANT *pcmdValue)
Definition: txtrange.c:1552
static HRESULT WINAPI HTMLTxtRange_getBookmark(IHTMLTxtRange *iface, BSTR *Bookmark)
Definition: txtrange.c:1497
static dispex_static_data_t HTMLTxtRange_dispex
Definition: txtrange.c:1715
static void wstrbuf_append_node_rec(wstrbuf_t *buf, nsIDOMNode *node)
Definition: txtrange.c:439
static HRESULT WINAPI HTMLTxtRange_findText(IHTMLTxtRange *iface, BSTR String, LONG count, LONG Flags, VARIANT_BOOL *Success)
Definition: txtrange.c:1482
static BOOL rangepoint_prev_node(rangepoint_t *iter)
Definition: txtrange.c:250
static HRESULT WINAPI HTMLTxtRange_compareEndPoints(IHTMLTxtRange *iface, BSTR how, IHTMLTxtRange *SourceRange, LONG *ret)
Definition: txtrange.c:1455
static const tid_t HTMLTxtRange_iface_tids[]
Definition: txtrange.c:1711
static void wstrbuf_append_len(wstrbuf_t *buf, LPCWSTR str, int len)
Definition: txtrange.c:359
static const WCHAR brW[]
Definition: txtrange.c:21
static HRESULT WINAPI HTMLTxtRange_GetIDsOfNames(IHTMLTxtRange *iface, REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
Definition: txtrange.c:877
static const IOleCommandTargetVtbl OleCommandTargetVtbl
Definition: txtrange.c:1703
static HRESULT WINAPI HTMLTxtRange_queryCommandSupported(IHTMLTxtRange *iface, BSTR cmdID, VARIANT_BOOL *pfRet)
Definition: txtrange.c:1512
static void get_start_point(HTMLTxtRange *This, rangepoint_t *ret)
Definition: txtrange.c:280
static HTMLTxtRange * impl_from_IOleCommandTarget(IOleCommandTarget *iface)
Definition: txtrange.c:1616
static HRESULT WINAPI RangeCommandTarget_QueryInterface(IOleCommandTarget *iface, REFIID riid, void **ppv)
Definition: txtrange.c:1621
static HRESULT WINAPI HTMLTxtRange_Invoke(IHTMLTxtRange *iface, DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
Definition: txtrange.c:887
static const WCHAR hrW[]
Definition: txtrange.c:22
static HRESULT WINAPI HTMLTxtRange_queryCommandEnabled(IHTMLTxtRange *iface, BSTR cmdID, VARIANT_BOOL *pfRet)
Definition: txtrange.c:1520
static ULONG WINAPI RangeCommandTarget_AddRef(IOleCommandTarget *iface)
Definition: txtrange.c:1627
static UINT32 get_child_count(nsIDOMNode *node)
Definition: txtrange.c:218
static HRESULT WINAPI HTMLTxtRange_isEqual(IHTMLTxtRange *iface, IHTMLTxtRange *Range, VARIANT_BOOL *IsEqual)
Definition: txtrange.c:1067
static BOOL is_elem_tag(nsIDOMNode *node, LPCWSTR istag)
Definition: txtrange.c:320
static BOOL rangepoint_next_node(rangepoint_t *iter)
Definition: txtrange.c:190
static HRESULT WINAPI HTMLTxtRange_queryCommandText(IHTMLTxtRange *iface, BSTR cmdID, BSTR *pcmdText)
Definition: txtrange.c:1544
static void init_rangepoint(rangepoint_t *rangepoint, nsIDOMNode *node, UINT32 off)
Definition: txtrange.c:171
static LONG find_prev_space(rangepoint_t *iter, BOOL first_space)
Definition: txtrange.c:731
static HRESULT WINAPI HTMLTxtRange_duplicate(IHTMLTxtRange *iface, IHTMLTxtRange **Duplicate)
Definition: txtrange.c:1021
static void set_start_point(HTMLTxtRange *This, const rangepoint_t *start)
Definition: txtrange.c:306
static HRESULT WINAPI HTMLTxtRange_inRange(IHTMLTxtRange *iface, IHTMLTxtRange *Range, VARIANT_BOOL *InRange)
Definition: txtrange.c:1036
static HRESULT WINAPI HTMLTxtRange_GetTypeInfo(IHTMLTxtRange *iface, UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
Definition: txtrange.c:869
static HRESULT WINAPI HTMLTxtRange_select(IHTMLTxtRange *iface)
Definition: txtrange.c:1308
static HTMLTxtRange * impl_from_IHTMLTxtRange(IHTMLTxtRange *iface)
Definition: txtrange.c:804
static HRESULT WINAPI HTMLTxtRange_QueryInterface(IHTMLTxtRange *iface, REFIID riid, void **ppv)
Definition: txtrange.c:809
static HRESULT WINAPI HTMLTxtRange_queryCommandState(IHTMLTxtRange *iface, BSTR cmdID, VARIANT_BOOL *pfRet)
Definition: txtrange.c:1528
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
Definition: dlist.c:348
Definition: pdh_main.c:94
@ Start
Definition: partlist.h:33
int ret
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:531
#define WINAPI
Definition: msvc.h:6
#define E_NOINTERFACE
Definition: winerror.h:2364
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185