• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (C) Research In Motion Limited 2010. All rights reserved.
3  *  Copyright (C) 2010 Joone Hur <joone@kldp.org>
4  *  Copyright (C) 2009 Google Inc. All rights reserved.
5  *  Copyright (C) 2011 Igalia S.L.
6  *
7  *  This library is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU Lesser General Public
9  *  License as published by the Free Software Foundation; either
10  *  version 2 of the License, or (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public
18  *  License along with this library; if not, write to the Free Software
19  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21 
22 #include "config.h"
23 #include "DumpRenderTreeSupportGtk.h"
24 
25 #include "APICast.h"
26 #include "AXObjectCache.h"
27 #include "AccessibilityObjectWrapperAtk.h"
28 #include "AnimationController.h"
29 #include "DOMWrapperWorld.h"
30 #include "Document.h"
31 #include "Element.h"
32 #include "FocusController.h"
33 #include "FrameLoaderClientGtk.h"
34 #include "FrameTree.h"
35 #include "FrameView.h"
36 #include "GCController.h"
37 #include "GraphicsContext.h"
38 #include "HTMLInputElement.h"
39 #include "InputElement.h"
40 #include "JSDOMWindow.h"
41 #include "JSDocument.h"
42 #include "JSElement.h"
43 #include "JSLock.h"
44 #include "JSNodeList.h"
45 #include "JSRange.h"
46 #include "JSValue.h"
47 #include "NodeList.h"
48 #include "PageGroup.h"
49 #include "PlatformString.h"
50 #include "PrintContext.h"
51 #include "RenderListItem.h"
52 #include "RenderTreeAsText.h"
53 #include "RenderView.h"
54 #include "SecurityOrigin.h"
55 #include "Settings.h"
56 #include "TextIterator.h"
57 #include "WebKitDOMRangePrivate.h"
58 #include "WorkerThread.h"
59 #include "webkitglobalsprivate.h"
60 #include "webkitwebframe.h"
61 #include "webkitwebframeprivate.h"
62 #include "webkitwebview.h"
63 #include "webkitwebviewprivate.h"
64 #include <JavaScriptCore/APICast.h>
65 
66 #if ENABLE(SVG)
67 #include "SVGDocumentExtensions.h"
68 #include "SVGSMILElement.h"
69 #endif
70 
71 using namespace JSC;
72 using namespace WebCore;
73 using namespace WebKit;
74 
75 bool DumpRenderTreeSupportGtk::s_drtRun = false;
76 bool DumpRenderTreeSupportGtk::s_linksIncludedInTabChain = true;
77 bool DumpRenderTreeSupportGtk::s_selectTrailingWhitespaceEnabled = false;
78 
DumpRenderTreeSupportGtk()79 DumpRenderTreeSupportGtk::DumpRenderTreeSupportGtk()
80 {
81 }
82 
~DumpRenderTreeSupportGtk()83 DumpRenderTreeSupportGtk::~DumpRenderTreeSupportGtk()
84 {
85 }
86 
setDumpRenderTreeModeEnabled(bool enabled)87 void DumpRenderTreeSupportGtk::setDumpRenderTreeModeEnabled(bool enabled)
88 {
89     s_drtRun = enabled;
90 }
91 
dumpRenderTreeModeEnabled()92 bool DumpRenderTreeSupportGtk::dumpRenderTreeModeEnabled()
93 {
94     return s_drtRun;
95 }
setLinksIncludedInFocusChain(bool enabled)96 void DumpRenderTreeSupportGtk::setLinksIncludedInFocusChain(bool enabled)
97 {
98     s_linksIncludedInTabChain = enabled;
99 }
100 
linksIncludedInFocusChain()101 bool DumpRenderTreeSupportGtk::linksIncludedInFocusChain()
102 {
103     return s_linksIncludedInTabChain;
104 }
105 
setSelectTrailingWhitespaceEnabled(bool enabled)106 void DumpRenderTreeSupportGtk::setSelectTrailingWhitespaceEnabled(bool enabled)
107 {
108     s_selectTrailingWhitespaceEnabled = enabled;
109 }
110 
selectTrailingWhitespaceEnabled()111 bool DumpRenderTreeSupportGtk::selectTrailingWhitespaceEnabled()
112 {
113     return s_selectTrailingWhitespaceEnabled;
114 }
115 
nodesFromRect(JSContextRef context,JSValueRef value,int x,int y,unsigned top,unsigned right,unsigned bottom,unsigned left,bool ignoreClipping)116 JSValueRef DumpRenderTreeSupportGtk::nodesFromRect(JSContextRef context, JSValueRef value, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping)
117 {
118     JSLock lock(SilenceAssertionsOnly);
119     ExecState* exec = toJS(context);
120     if (!value)
121         return JSValueMakeUndefined(context);
122     JSValue jsValue = toJS(exec, value);
123     if (!jsValue.inherits(&JSDocument::s_info))
124        return JSValueMakeUndefined(context);
125 
126     JSDocument* jsDocument = static_cast<JSDocument*>(asObject(jsValue));
127     Document* document = jsDocument->impl();
128     RefPtr<NodeList> nodes = document->nodesFromRect(x, y, top, right, bottom, left, ignoreClipping);
129     return toRef(exec, toJS(exec, jsDocument->globalObject(), nodes.get()));
130 }
131 
jsValueToDOMRange(JSContextRef context,JSValueRef value)132 WebKitDOMRange* DumpRenderTreeSupportGtk::jsValueToDOMRange(JSContextRef context, JSValueRef value)
133 {
134     if (!value)
135         return 0;
136 
137     JSLock lock(SilenceAssertionsOnly);
138     ExecState* exec = toJS(context);
139 
140     Range* range = toRange(toJS(exec, value));
141     if (!range)
142         return 0;
143     return kit(range);
144 }
145 
146 /**
147  * getFrameChildren:
148  * @frame: a #WebKitWebFrame
149  *
150  * Return value: child frames of @frame
151  */
getFrameChildren(WebKitWebFrame * frame)152 GSList* DumpRenderTreeSupportGtk::getFrameChildren(WebKitWebFrame* frame)
153 {
154     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
155 
156     Frame* coreFrame = core(frame);
157     if (!coreFrame)
158         return 0;
159 
160     GSList* children = 0;
161     for (Frame* child = coreFrame->tree()->firstChild(); child; child = child->tree()->nextSibling()) {
162         FrameLoader* loader = child->loader();
163         WebKit::FrameLoaderClient* client = static_cast<WebKit::FrameLoaderClient*>(loader->client());
164         if (client)
165           children = g_slist_append(children, client->webFrame());
166     }
167 
168     return children;
169 }
170 
171 /**
172  * getInnerText:
173  * @frame: a #WebKitWebFrame
174  *
175  * Return value: inner text of @frame
176  */
getInnerText(WebKitWebFrame * frame)177 CString DumpRenderTreeSupportGtk::getInnerText(WebKitWebFrame* frame)
178 {
179     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), CString(""));
180 
181     Frame* coreFrame = core(frame);
182     if (!coreFrame)
183         return CString("");
184 
185     FrameView* view = coreFrame->view();
186 
187     if (view && view->layoutPending())
188         view->layout();
189 
190     Element* documentElement = coreFrame->document()->documentElement();
191     return documentElement->innerText().utf8();
192 }
193 
194 /**
195  * dumpRenderTree:
196  * @frame: a #WebKitWebFrame
197  *
198  * Return value: Non-recursive render tree dump of @frame
199  */
dumpRenderTree(WebKitWebFrame * frame)200 CString DumpRenderTreeSupportGtk::dumpRenderTree(WebKitWebFrame* frame)
201 {
202     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), CString(""));
203 
204     Frame* coreFrame = core(frame);
205     if (!coreFrame)
206         return CString("");
207 
208     FrameView* view = coreFrame->view();
209 
210     if (view && view->layoutPending())
211         view->layout();
212 
213     return externalRepresentation(coreFrame).utf8();
214 }
215 
216 /**
217  * counterValueForElementById:
218  * @frame: a #WebKitWebFrame
219  * @id: an element ID string
220  *
221  * Return value: The counter value of element @id in @frame
222  */
counterValueForElementById(WebKitWebFrame * frame,const char * id)223 CString DumpRenderTreeSupportGtk::counterValueForElementById(WebKitWebFrame* frame, const char* id)
224 {
225     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), CString());
226 
227     Frame* coreFrame = core(frame);
228     if (!coreFrame)
229         return CString();
230 
231     Element* coreElement = coreFrame->document()->getElementById(AtomicString(id));
232     if (!coreElement)
233         return CString();
234 
235     return counterValueForElement(coreElement).utf8();
236 }
237 
238 /**
239  * numberForElementById
240  * @frame: a #WebKitWebFrame
241  * @id: an element ID string
242  * @pageWidth: width of a page
243  * @pageHeight: height of a page
244  *
245  * Return value: The number of page where the specified element will be put
246  */
pageNumberForElementById(WebKitWebFrame * frame,const char * id,float pageWidth,float pageHeight)247 int DumpRenderTreeSupportGtk::pageNumberForElementById(WebKitWebFrame* frame, const char* id, float pageWidth, float pageHeight)
248 {
249     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
250 
251     Frame* coreFrame = core(frame);
252     if (!coreFrame)
253         return -1;
254 
255     Element* coreElement = coreFrame->document()->getElementById(AtomicString(id));
256     if (!coreElement)
257         return -1;
258     return PrintContext::pageNumberForElement(coreElement, FloatSize(pageWidth, pageHeight));
259 }
260 
261 /**
262  * numberOfPagesForFrame
263  * @frame: a #WebKitWebFrame
264  * @pageWidth: width of a page
265  * @pageHeight: height of a page
266  *
267  * Return value: The number of pages to be printed.
268  */
numberOfPagesForFrame(WebKitWebFrame * frame,float pageWidth,float pageHeight)269 int DumpRenderTreeSupportGtk::numberOfPagesForFrame(WebKitWebFrame* frame, float pageWidth, float pageHeight)
270 {
271     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
272 
273     Frame* coreFrame = core(frame);
274     if (!coreFrame)
275         return -1;
276 
277     return PrintContext::numberOfPages(coreFrame, FloatSize(pageWidth, pageHeight));
278 }
279 
280 /**
281  * pageProperty
282  * @frame: a #WebKitWebFrame
283  * @propertyName: name of a property
284  * @pageNumber: number of a page
285  *
286  * Return value: The value of the given property name.
287  */
pageProperty(WebKitWebFrame * frame,const char * propertyName,int pageNumber)288 CString DumpRenderTreeSupportGtk::pageProperty(WebKitWebFrame* frame, const char* propertyName, int pageNumber)
289 {
290     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), CString());
291 
292     Frame* coreFrame = core(frame);
293     if (!coreFrame)
294         return CString();
295 
296     return PrintContext::pageProperty(coreFrame, propertyName, pageNumber).utf8();
297 }
298 
299 /**
300  * isPageBoxVisible
301  * @frame: a #WebKitWebFrame
302  * @pageNumber: number of a page
303  *
304  * Return value: TRUE if a page box is visible.
305  */
isPageBoxVisible(WebKitWebFrame * frame,int pageNumber)306 bool DumpRenderTreeSupportGtk::isPageBoxVisible(WebKitWebFrame* frame, int pageNumber)
307 {
308     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), false);
309 
310     Frame* coreFrame = core(frame);
311     if (!coreFrame)
312         return false;
313 
314     return coreFrame->document()->isPageBoxVisible(pageNumber);
315 }
316 
317 /**
318  * pageSizeAndMarginsInPixels
319  * @frame: a #WebKitWebFrame
320  * @pageNumber: number of a page
321  * @width: width of a page
322  * @height: height of a page
323  * @marginTop: top margin of a page
324  * @marginRight: right margin of a page
325  * @marginBottom: bottom margin of a page
326  * @marginLeft: left margin of a page
327  *
328  * Return value: The value of page size and margin.
329  */
pageSizeAndMarginsInPixels(WebKitWebFrame * frame,int pageNumber,int width,int height,int marginTop,int marginRight,int marginBottom,int marginLeft)330 CString DumpRenderTreeSupportGtk::pageSizeAndMarginsInPixels(WebKitWebFrame* frame, int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft)
331 {
332     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), CString());
333 
334     Frame* coreFrame = core(frame);
335     if (!coreFrame)
336         return CString();
337 
338     return PrintContext::pageSizeAndMarginsInPixels(coreFrame, pageNumber, width, height, marginTop, marginRight, marginBottom, marginLeft).utf8();
339 }
340 
341 /**
342  * addUserStyleSheet
343  * @frame: a #WebKitWebFrame
344  * @sourceCode: code of a user stylesheet
345  *
346  */
addUserStyleSheet(WebKitWebFrame * frame,const char * sourceCode,bool allFrames)347 void DumpRenderTreeSupportGtk::addUserStyleSheet(WebKitWebFrame* frame, const char* sourceCode, bool allFrames)
348 {
349     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
350 
351     Frame* coreFrame = core(frame);
352     if (!coreFrame)
353         return;
354 
355     WebKitWebView* webView = getViewFromFrame(frame);
356     Page* page = core(webView);
357     page->group().addUserStyleSheetToWorld(mainThreadNormalWorld(), sourceCode, KURL(), 0, 0, allFrames ? InjectInAllFrames : InjectInTopFrameOnly);
358 }
359 
360 /**
361  * getPendingUnloadEventCount:
362  * @frame: a #WebKitWebFrame
363  *
364  * Return value: number of pending unload events
365  */
getPendingUnloadEventCount(WebKitWebFrame * frame)366 guint DumpRenderTreeSupportGtk::getPendingUnloadEventCount(WebKitWebFrame* frame)
367 {
368     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
369 
370     return core(frame)->domWindow()->pendingUnloadEventListeners();
371 }
372 
pauseAnimation(WebKitWebFrame * frame,const char * name,double time,const char * element)373 bool DumpRenderTreeSupportGtk::pauseAnimation(WebKitWebFrame* frame, const char* name, double time, const char* element)
374 {
375     ASSERT(core(frame));
376     Element* coreElement = core(frame)->document()->getElementById(AtomicString(element));
377     if (!coreElement || !coreElement->renderer())
378         return false;
379     return core(frame)->animation()->pauseAnimationAtTime(coreElement->renderer(), AtomicString(name), time);
380 }
381 
pauseTransition(WebKitWebFrame * frame,const char * name,double time,const char * element)382 bool DumpRenderTreeSupportGtk::pauseTransition(WebKitWebFrame* frame, const char* name, double time, const char* element)
383 {
384     ASSERT(core(frame));
385     Element* coreElement = core(frame)->document()->getElementById(AtomicString(element));
386     if (!coreElement || !coreElement->renderer())
387         return false;
388     return core(frame)->animation()->pauseTransitionAtTime(coreElement->renderer(), AtomicString(name), time);
389 }
390 
pauseSVGAnimation(WebKitWebFrame * frame,const char * animationId,double time,const char * elementId)391 bool DumpRenderTreeSupportGtk::pauseSVGAnimation(WebKitWebFrame* frame, const char* animationId, double time, const char* elementId)
392 {
393     ASSERT(core(frame));
394 #if ENABLE(SVG)
395     Document* document = core(frame)->document();
396     if (!document || !document->svgExtensions())
397         return false;
398     Element* coreElement = document->getElementById(AtomicString(animationId));
399     if (!coreElement || !SVGSMILElement::isSMILElement(coreElement))
400         return false;
401     return document->accessSVGExtensions()->sampleAnimationAtTime(elementId, static_cast<SVGSMILElement*>(coreElement), time);
402 #else
403     return false;
404 #endif
405 }
406 
markerTextForListItem(WebKitWebFrame * frame,JSContextRef context,JSValueRef nodeObject)407 CString DumpRenderTreeSupportGtk::markerTextForListItem(WebKitWebFrame* frame, JSContextRef context, JSValueRef nodeObject)
408 {
409     JSC::ExecState* exec = toJS(context);
410     Element* element = toElement(toJS(exec, nodeObject));
411     if (!element)
412         return CString();
413 
414     return WebCore::markerTextForListItem(element).utf8();
415 }
416 
numberOfActiveAnimations(WebKitWebFrame * frame)417 unsigned int DumpRenderTreeSupportGtk::numberOfActiveAnimations(WebKitWebFrame* frame)
418 {
419     Frame* coreFrame = core(frame);
420     if (!coreFrame)
421         return 0;
422 
423     return coreFrame->animation()->numberOfActiveAnimations();
424 }
425 
suspendAnimations(WebKitWebFrame * frame)426 void DumpRenderTreeSupportGtk::suspendAnimations(WebKitWebFrame* frame)
427 {
428     Frame* coreFrame = core(frame);
429     if (!coreFrame)
430         return;
431 
432     return coreFrame->animation()->suspendAnimations();
433 }
434 
resumeAnimations(WebKitWebFrame * frame)435 void DumpRenderTreeSupportGtk::resumeAnimations(WebKitWebFrame* frame)
436 {
437     Frame* coreFrame = core(frame);
438     if (!coreFrame)
439         return;
440 
441     return coreFrame->animation()->resumeAnimations();
442 }
443 
clearMainFrameName(WebKitWebFrame * frame)444 void DumpRenderTreeSupportGtk::clearMainFrameName(WebKitWebFrame* frame)
445 {
446     g_return_if_fail(WEBKIT_IS_WEB_FRAME(frame));
447 
448     core(frame)->tree()->clearName();
449 }
450 
getRootAccessibleElement(WebKitWebFrame * frame)451 AtkObject* DumpRenderTreeSupportGtk::getRootAccessibleElement(WebKitWebFrame* frame)
452 {
453     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), 0);
454 
455 #if HAVE(ACCESSIBILITY)
456     if (!AXObjectCache::accessibilityEnabled())
457         AXObjectCache::enableAccessibility();
458 
459     WebKitWebFramePrivate* priv = frame->priv;
460     if (!priv->coreFrame || !priv->coreFrame->document())
461         return 0;
462 
463     AtkObject* wrapper =  priv->coreFrame->document()->axObjectCache()->rootObject()->wrapper();
464     if (!wrapper)
465         return 0;
466 
467     return wrapper;
468 #else
469     return 0;
470 #endif
471 }
472 
getFocusedAccessibleElement(WebKitWebFrame * frame)473 AtkObject* DumpRenderTreeSupportGtk::getFocusedAccessibleElement(WebKitWebFrame* frame)
474 {
475 #if HAVE(ACCESSIBILITY)
476     AtkObject* wrapper = getRootAccessibleElement(frame);
477     if (!wrapper)
478         return 0;
479 
480     return webkit_accessible_get_focused_element(WEBKIT_ACCESSIBLE(wrapper));
481 #else
482     return 0;
483 #endif
484 }
485 
executeCoreCommandByName(WebKitWebView * webView,const gchar * name,const gchar * value)486 void DumpRenderTreeSupportGtk::executeCoreCommandByName(WebKitWebView* webView, const gchar* name, const gchar* value)
487 {
488     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
489     g_return_if_fail(name);
490     g_return_if_fail(value);
491 
492     core(webView)->focusController()->focusedOrMainFrame()->editor()->command(name).execute(value);
493 }
494 
isCommandEnabled(WebKitWebView * webView,const gchar * name)495 bool DumpRenderTreeSupportGtk::isCommandEnabled(WebKitWebView* webView, const gchar* name)
496 {
497     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
498     g_return_val_if_fail(name, FALSE);
499 
500     return core(webView)->focusController()->focusedOrMainFrame()->editor()->command(name).isEnabled();
501 }
502 
setComposition(WebKitWebView * webView,const char * text,int start,int end)503 void DumpRenderTreeSupportGtk::setComposition(WebKitWebView* webView, const char* text, int start, int end)
504 {
505     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
506     g_return_if_fail(text);
507 
508     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
509     if (!frame)
510         return;
511 
512     Editor* editor = frame->editor();
513     if (!editor)
514         return;
515     if (!editor->canEdit() && !editor->hasComposition())
516         return;
517 
518     String compositionString = String::fromUTF8(text);
519     Vector<CompositionUnderline> underlines;
520     underlines.append(CompositionUnderline(0, compositionString.length(), Color(0, 0, 0), false));
521     editor->setComposition(compositionString, underlines, start, end);
522 }
523 
confirmComposition(WebKitWebView * webView,const char * text)524 void DumpRenderTreeSupportGtk::confirmComposition(WebKitWebView* webView, const char* text)
525 {
526     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
527 
528     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
529     if (!frame)
530         return;
531 
532     Editor* editor = frame->editor();
533     if (!editor || (!editor->hasComposition() && !text))
534         return;
535 
536     if (editor->hasComposition()) {
537         if (text)
538             editor->confirmComposition(String::fromUTF8(text));
539         else
540             editor->confirmComposition();
541     } else
542         editor->insertText(String::fromUTF8(text), 0);
543 }
544 
firstRectForCharacterRange(WebKitWebView * webView,int location,int length,GdkRectangle * rect)545 bool DumpRenderTreeSupportGtk::firstRectForCharacterRange(WebKitWebView* webView, int location, int length, GdkRectangle* rect)
546 {
547     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), false);
548     g_return_val_if_fail(rect, false);
549 
550     if ((location + length < location) && (location + length))
551         length = 0;
552 
553     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
554     if (!frame)
555         return false;
556 
557     Editor* editor = frame->editor();
558     if (!editor)
559         return false;
560 
561     Element* selectionRoot = frame->selection()->rootEditableElement();
562     Element* scope = selectionRoot ? selectionRoot : frame->document()->documentElement();
563     RefPtr<Range> range = TextIterator::rangeFromLocationAndLength(scope, location, length);
564     if (!range)
565         return false;
566 
567     *rect = editor->firstRectForRange(range.get());
568 
569     return true;
570 }
571 
selectedRange(WebKitWebView * webView,int * start,int * end)572 bool DumpRenderTreeSupportGtk::selectedRange(WebKitWebView* webView, int* start, int* end)
573 {
574     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), false);
575     g_return_val_if_fail(start, false);
576     g_return_val_if_fail(end, false);
577 
578     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
579     if (!frame)
580         return false;
581 
582     RefPtr<Range> range = frame->selection()->toNormalizedRange().get();
583 
584     Element* selectionRoot = frame->selection()->rootEditableElement();
585     Element* scope = selectionRoot ? selectionRoot : frame->document()->documentElement();
586 
587     RefPtr<Range> testRange = Range::create(scope->document(), scope, 0, range->startContainer(), range->startOffset());
588     ASSERT(testRange->startContainer() == scope);
589     *start = TextIterator::rangeLength(testRange.get());
590 
591     ExceptionCode ec;
592     testRange->setEnd(range->endContainer(), range->endOffset(), ec);
593     ASSERT(testRange->startContainer() == scope);
594     *end = TextIterator::rangeLength(testRange.get());
595 
596     return true;
597 }
598 
whiteListAccessFromOrigin(const gchar * sourceOrigin,const gchar * destinationProtocol,const gchar * destinationHost,bool allowDestinationSubdomains)599 void DumpRenderTreeSupportGtk::whiteListAccessFromOrigin(const gchar* sourceOrigin, const gchar* destinationProtocol, const gchar* destinationHost, bool allowDestinationSubdomains)
600 {
601     SecurityOrigin::addOriginAccessWhitelistEntry(*SecurityOrigin::createFromString(sourceOrigin), destinationProtocol, destinationHost, allowDestinationSubdomains);
602 }
603 
resetOriginAccessWhiteLists()604 void DumpRenderTreeSupportGtk::resetOriginAccessWhiteLists()
605 {
606     SecurityOrigin::resetOriginAccessWhitelists();
607 }
608 
gcCollectJavascriptObjects()609 void DumpRenderTreeSupportGtk::gcCollectJavascriptObjects()
610 {
611     gcController().garbageCollectNow();
612 }
613 
gcCollectJavascriptObjectsOnAlternateThread(bool waitUntilDone)614 void DumpRenderTreeSupportGtk::gcCollectJavascriptObjectsOnAlternateThread(bool waitUntilDone)
615 {
616     gcController().garbageCollectOnAlternateThreadForDebugging(waitUntilDone);
617 }
618 
gcCountJavascriptObjects()619 unsigned long DumpRenderTreeSupportGtk::gcCountJavascriptObjects()
620 {
621     JSC::JSLock lock(JSC::SilenceAssertionsOnly);
622     return JSDOMWindow::commonJSGlobalData()->heap.objectCount();
623 }
624 
layoutFrame(WebKitWebFrame * frame)625 void DumpRenderTreeSupportGtk::layoutFrame(WebKitWebFrame* frame)
626 {
627     Frame* coreFrame = core(frame);
628     if (!coreFrame)
629         return;
630 
631     FrameView* view = coreFrame->view();
632     if (!view)
633         return;
634 
635     view->layout();
636 }
637 
638 // For testing fast/viewport.
dumpConfigurationForViewport(WebKitWebView * webView,gint deviceDPI,gint deviceWidth,gint deviceHeight,gint availableWidth,gint availableHeight)639 void DumpRenderTreeSupportGtk::dumpConfigurationForViewport(WebKitWebView* webView, gint deviceDPI, gint deviceWidth, gint deviceHeight, gint availableWidth, gint availableHeight)
640 {
641     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
642 
643     ViewportArguments arguments = webView->priv->corePage->mainFrame()->document()->viewportArguments();
644     ViewportAttributes attrs = computeViewportAttributes(arguments, /* default layout width for non-mobile pages */ 980, deviceWidth, deviceHeight, deviceDPI, IntSize(availableWidth, availableHeight));
645 
646     fprintf(stdout, "viewport size %dx%d scale %f with limits [%f, %f] and userScalable %f\n", attrs.layoutSize.width(), attrs.layoutSize.height(), attrs.initialScale, attrs.minimumScale, attrs.maximumScale, attrs.userScalable);
647 }
648 
clearOpener(WebKitWebFrame * frame)649 void DumpRenderTreeSupportGtk::clearOpener(WebKitWebFrame* frame)
650 {
651     Frame* coreFrame = core(frame);
652     if (coreFrame)
653         coreFrame->loader()->setOpener(0);
654 }
655 
shadowRoot(JSContextRef context,JSValueRef value)656 JSValueRef DumpRenderTreeSupportGtk::shadowRoot(JSContextRef context, JSValueRef value)
657 {
658     JSLock lock(SilenceAssertionsOnly);
659     JSC::ExecState* exec = toJS(context);
660     Element* element = toElement(toJS(exec, value));
661     if (!element)
662         return JSValueMakeNull(context);
663 
664     return toRef(exec, toJS(exec, element->shadowRoot()));
665 }
666 
workerThreadCount()667 unsigned int DumpRenderTreeSupportGtk::workerThreadCount()
668 {
669 #if ENABLE(WORKERS)
670     return WebCore::WorkerThread::workerThreadCount();
671 #else
672     return 0;
673 #endif
674 }
675 
webkitWebFrameSelectionHasSpellingMarker(WebKitWebFrame * frame,gint from,gint length)676 bool DumpRenderTreeSupportGtk::webkitWebFrameSelectionHasSpellingMarker(WebKitWebFrame *frame, gint from, gint length)
677 {
678     g_return_val_if_fail(WEBKIT_IS_WEB_FRAME(frame), FALSE);
679 
680     return core(frame)->editor()->selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
681 }
682 
findString(WebKitWebView * webView,const gchar * targetString,WebKitFindOptions findOptions)683 bool DumpRenderTreeSupportGtk::findString(WebKitWebView* webView, const gchar* targetString, WebKitFindOptions findOptions)
684 {
685     return core(webView)->findString(String::fromUTF8(targetString), findOptions);
686 }
687 
defaultMinimumTimerInterval()688 double DumpRenderTreeSupportGtk::defaultMinimumTimerInterval()
689 {
690     return Settings::defaultMinDOMTimerInterval();
691 }
692 
setMinimumTimerInterval(WebKitWebView * webView,double interval)693 void DumpRenderTreeSupportGtk::setMinimumTimerInterval(WebKitWebView* webView, double interval)
694 {
695     core(webView)->settings()->setMinDOMTimerInterval(interval);
696 }
697 
modifyAccessibilityValue(AtkObject * axObject,bool increment)698 static void modifyAccessibilityValue(AtkObject* axObject, bool increment)
699 {
700     if (!axObject || !WEBKIT_IS_ACCESSIBLE(axObject))
701         return;
702 
703     AccessibilityObject* coreObject = webkit_accessible_get_accessibility_object(WEBKIT_ACCESSIBLE(axObject));
704     if (!coreObject)
705         return;
706 
707     if (increment)
708         coreObject->increment();
709     else
710         coreObject->decrement();
711 }
712 
incrementAccessibilityValue(AtkObject * axObject)713 void DumpRenderTreeSupportGtk::incrementAccessibilityValue(AtkObject* axObject)
714 {
715     modifyAccessibilityValue(axObject, true);
716 }
717 
decrementAccessibilityValue(AtkObject * axObject)718 void DumpRenderTreeSupportGtk::decrementAccessibilityValue(AtkObject* axObject)
719 {
720     modifyAccessibilityValue(axObject, false);
721 }
722 
setAutofilled(JSContextRef context,JSValueRef nodeObject,bool autofilled)723 void DumpRenderTreeSupportGtk::setAutofilled(JSContextRef context, JSValueRef nodeObject, bool autofilled)
724 {
725     JSC::ExecState* exec = toJS(context);
726     Element* element = toElement(toJS(exec, nodeObject));
727     if (!element)
728         return;
729     InputElement* inputElement = element->toInputElement();
730     if (!inputElement)
731         return;
732 
733     static_cast<HTMLInputElement*>(inputElement)->setAutofilled(autofilled);
734 }
735 
setValueForUser(JSContextRef context,JSValueRef nodeObject,JSStringRef value)736 void DumpRenderTreeSupportGtk::setValueForUser(JSContextRef context, JSValueRef nodeObject, JSStringRef value)
737 {
738     JSC::ExecState* exec = toJS(context);
739     Element* element = toElement(toJS(exec, nodeObject));
740     if (!element)
741         return;
742     InputElement* inputElement = element->toInputElement();
743     if (!inputElement)
744         return;
745 
746     size_t bufferSize = JSStringGetMaximumUTF8CStringSize(value);
747     GOwnPtr<gchar> valueBuffer(static_cast<gchar*>(g_malloc(bufferSize)));
748     JSStringGetUTF8CString(value, valueBuffer.get(), bufferSize);
749     inputElement->setValueForUser(String::fromUTF8(valueBuffer.get()));
750 }
751 
rectangleForSelection(WebKitWebFrame * frame,GdkRectangle * rectangle)752 void DumpRenderTreeSupportGtk::rectangleForSelection(WebKitWebFrame* frame, GdkRectangle* rectangle)
753 {
754     Frame* coreFrame = core(frame);
755     if (!coreFrame)
756         return;
757 
758     IntRect bounds = enclosingIntRect(coreFrame->selection()->bounds());
759     rectangle->x = bounds.x();
760     rectangle->y = bounds.y();
761     rectangle->width = bounds.width();
762     rectangle->height = bounds.height();
763 }
764