1 /* 2 * Copyright (C) Research In Motion Limited 2010. All rights reserved. 3 * Copyright (C) 2010 Joone Hur <joone (at) 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 79 DumpRenderTreeSupportGtk::DumpRenderTreeSupportGtk() 80 { 81 } 82 83 DumpRenderTreeSupportGtk::~DumpRenderTreeSupportGtk() 84 { 85 } 86 87 void DumpRenderTreeSupportGtk::setDumpRenderTreeModeEnabled(bool enabled) 88 { 89 s_drtRun = enabled; 90 } 91 92 bool DumpRenderTreeSupportGtk::dumpRenderTreeModeEnabled() 93 { 94 return s_drtRun; 95 } 96 void DumpRenderTreeSupportGtk::setLinksIncludedInFocusChain(bool enabled) 97 { 98 s_linksIncludedInTabChain = enabled; 99 } 100 101 bool DumpRenderTreeSupportGtk::linksIncludedInFocusChain() 102 { 103 return s_linksIncludedInTabChain; 104 } 105 106 void DumpRenderTreeSupportGtk::setSelectTrailingWhitespaceEnabled(bool enabled) 107 { 108 s_selectTrailingWhitespaceEnabled = enabled; 109 } 110 111 bool DumpRenderTreeSupportGtk::selectTrailingWhitespaceEnabled() 112 { 113 return s_selectTrailingWhitespaceEnabled; 114 } 115 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 604 void DumpRenderTreeSupportGtk::resetOriginAccessWhiteLists() 605 { 606 SecurityOrigin::resetOriginAccessWhitelists(); 607 } 608 609 void DumpRenderTreeSupportGtk::gcCollectJavascriptObjects() 610 { 611 gcController().garbageCollectNow(); 612 } 613 614 void DumpRenderTreeSupportGtk::gcCollectJavascriptObjectsOnAlternateThread(bool waitUntilDone) 615 { 616 gcController().garbageCollectOnAlternateThreadForDebugging(waitUntilDone); 617 } 618 619 unsigned long DumpRenderTreeSupportGtk::gcCountJavascriptObjects() 620 { 621 JSC::JSLock lock(JSC::SilenceAssertionsOnly); 622 return JSDOMWindow::commonJSGlobalData()->heap.objectCount(); 623 } 624 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. 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 649 void DumpRenderTreeSupportGtk::clearOpener(WebKitWebFrame* frame) 650 { 651 Frame* coreFrame = core(frame); 652 if (coreFrame) 653 coreFrame->loader()->setOpener(0); 654 } 655 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 667 unsigned int DumpRenderTreeSupportGtk::workerThreadCount() 668 { 669 #if ENABLE(WORKERS) 670 return WebCore::WorkerThread::workerThreadCount(); 671 #else 672 return 0; 673 #endif 674 } 675 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 683 bool DumpRenderTreeSupportGtk::findString(WebKitWebView* webView, const gchar* targetString, WebKitFindOptions findOptions) 684 { 685 return core(webView)->findString(String::fromUTF8(targetString), findOptions); 686 } 687 688 double DumpRenderTreeSupportGtk::defaultMinimumTimerInterval() 689 { 690 return Settings::defaultMinDOMTimerInterval(); 691 } 692 693 void DumpRenderTreeSupportGtk::setMinimumTimerInterval(WebKitWebView* webView, double interval) 694 { 695 core(webView)->settings()->setMinDOMTimerInterval(interval); 696 } 697 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 713 void DumpRenderTreeSupportGtk::incrementAccessibilityValue(AtkObject* axObject) 714 { 715 modifyAccessibilityValue(axObject, true); 716 } 717 718 void DumpRenderTreeSupportGtk::decrementAccessibilityValue(AtkObject* axObject) 719 { 720 modifyAccessibilityValue(axObject, false); 721 } 722 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 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 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