1/* 2 Copyright (C) 2011 ProFUSION embedded systems 3 Copyright (C) 2011 Samsung Electronics 4 Copyright (C) 2012 Intel Corporation. All rights reserved. 5 6 This library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Library General Public 8 License as published by the Free Software Foundation; either 9 version 2 of the License, or (at your option) any later version. 10 11 This library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Library General Public License for more details. 15 16 You should have received a copy of the GNU Library General Public License 17 along with this library; see the file COPYING.LIB. If not, write to 18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 Boston, MA 02110-1301, USA. 20*/ 21 22#include "config.h" 23#include "DumpRenderTreeSupportEfl.h" 24 25#include "FrameLoaderClientEfl.h" 26#include "ewk_frame_private.h" 27#include "ewk_history_private.h" 28#include "ewk_private.h" 29#include "ewk_view_private.h" 30 31#include <APICast.h> 32#include <AnimationController.h> 33#include <DOMWindow.h> 34#include <DocumentLoader.h> 35#include <Editor.h> 36#include <EditorClientEfl.h> 37#include <Eina.h> 38#include <Evas.h> 39#include <FindOptions.h> 40#include <FloatSize.h> 41#include <FocusController.h> 42#include <FrameLoader.h> 43#include <FrameSelection.h> 44#include <FrameView.h> 45#include <HTMLInputElement.h> 46#include <InspectorController.h> 47#include <IntRect.h> 48#include <JSCSSStyleDeclaration.h> 49#include <JSDOMWindow.h> 50#include <JSElement.h> 51#include <JavaScriptCore/OpaqueJSString.h> 52#include <MemoryCache.h> 53#include <MutationObserver.h> 54#include <PageGroup.h> 55#include <PrintContext.h> 56#include <RenderTreeAsText.h> 57#include <ResourceLoadScheduler.h> 58#include <RuntimeEnabledFeatures.h> 59#include <SchemeRegistry.h> 60#include <ScriptController.h> 61#include <ScriptValue.h> 62#include <Settings.h> 63#include <TextIterator.h> 64#include <bindings/js/GCController.h> 65#include <history/HistoryItem.h> 66#include <wtf/HashMap.h> 67 68#if ENABLE(GEOLOCATION) 69#include <GeolocationClientMock.h> 70#include <GeolocationController.h> 71#include <GeolocationError.h> 72#include <GeolocationPosition.h> 73#include <wtf/CurrentTime.h> 74#endif 75 76#if HAVE(ACCESSIBILITY) 77#include "AXObjectCache.h" 78#include "AccessibilityObject.h" 79#include "WebKitAccessibleWrapperAtk.h" 80#endif 81 82#define DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, ...) \ 83 WebCore::Frame* frame = EWKPrivate::coreFrame(ewkFrame); \ 84 if (!frame) \ 85 return __VA_ARGS__; 86 87#define DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page, ...) \ 88 WebCore::Page* page = EWKPrivate::corePage(ewkView); \ 89 if (!page) \ 90 return __VA_ARGS__; 91 92bool DumpRenderTreeSupportEfl::s_drtRun = false; 93 94void DumpRenderTreeSupportEfl::setDumpRenderTreeModeEnabled(bool enabled) 95{ 96 s_drtRun = enabled; 97} 98 99bool DumpRenderTreeSupportEfl::dumpRenderTreeModeEnabled() 100{ 101 return s_drtRun; 102} 103 104bool DumpRenderTreeSupportEfl::callShouldCloseOnWebView(Evas_Object* ewkFrame) 105{ 106 DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, false); 107 108 return frame->loader()->shouldClose(); 109} 110 111void DumpRenderTreeSupportEfl::clearFrameName(Evas_Object* ewkFrame) 112{ 113 DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame); 114 115 frame->tree()->clearName(); 116} 117 118void DumpRenderTreeSupportEfl::clearOpener(Evas_Object* ewkFrame) 119{ 120 DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame); 121 122 frame->loader()->setOpener(0); 123} 124 125String DumpRenderTreeSupportEfl::layerTreeAsText(const Evas_Object* ewkFrame) 126{ 127 DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, String()); 128 129 return frame->layerTreeAsText(); 130} 131 132Eina_List* DumpRenderTreeSupportEfl::frameChildren(const Evas_Object* ewkFrame) 133{ 134 DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, 0); 135 136 Eina_List* childFrames = 0; 137 138 for (unsigned index = 0; index < frame->tree()->childCount(); index++) { 139 WebCore::Frame *childFrame = frame->tree()->child(index); 140 WebCore::FrameLoaderClientEfl *client = static_cast<WebCore::FrameLoaderClientEfl*>(childFrame->loader()->client()); 141 142 if (!client) 143 continue; 144 145 childFrames = eina_list_append(childFrames, client->webFrame()); 146 } 147 148 return childFrames; 149} 150 151WebCore::Frame* DumpRenderTreeSupportEfl::frameParent(const Evas_Object* ewkFrame) 152{ 153 DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, 0); 154 155 return frame->tree()->parent(); 156} 157 158void DumpRenderTreeSupportEfl::layoutFrame(Evas_Object* ewkFrame) 159{ 160 DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame); 161 162 if (!frame->view()) 163 return; 164 165 frame->view()->layout(); 166} 167 168unsigned DumpRenderTreeSupportEfl::pendingUnloadEventCount(const Evas_Object* ewkFrame) 169{ 170 DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, 0); 171 172 return frame->document()->domWindow()->pendingUnloadEventListeners(); 173} 174 175String DumpRenderTreeSupportEfl::renderTreeDump(Evas_Object* ewkFrame) 176{ 177 DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, String()); 178 179 WebCore::FrameView *frameView = frame->view(); 180 181 if (frameView && frameView->layoutPending()) 182 frameView->layout(); 183 184 return WebCore::externalRepresentation(frame); 185} 186 187String DumpRenderTreeSupportEfl::responseMimeType(const Evas_Object* ewkFrame) 188{ 189 DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, String()); 190 191 WebCore::DocumentLoader *documentLoader = frame->loader()->documentLoader(); 192 193 if (!documentLoader) 194 return String(); 195 196 return documentLoader->responseMIMEType(); 197} 198 199WebCore::IntRect DumpRenderTreeSupportEfl::selectionRectangle(const Evas_Object* ewkFrame) 200{ 201 DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, WebCore::IntRect()); 202 203 return enclosingIntRect(frame->selection()->bounds()); 204} 205 206// Compare with "WebKit/Tools/DumpRenderTree/mac/FrameLoadDelegate.mm 207String DumpRenderTreeSupportEfl::suitableDRTFrameName(const Evas_Object* ewkFrame) 208{ 209 DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, String()); 210 211 const String frameName(ewk_frame_name_get(ewkFrame)); 212 213 if (ewkFrame == ewk_view_frame_main_get(ewk_frame_view_get(ewkFrame))) { 214 if (!frameName.isEmpty()) 215 return String("main frame \"") + frameName + String("\""); 216 217 return String("main frame"); 218 } 219 220 if (!frameName.isEmpty()) 221 return String("frame \"") + frameName + String("\""); 222 223 return String("frame (anonymous)"); 224} 225 226void DumpRenderTreeSupportEfl::setValueForUser(JSContextRef context, JSValueRef nodeObject, const String& value) 227{ 228 JSC::ExecState* exec = toJS(context); 229 WebCore::Element* element = WebCore::toElement(toJS(exec, nodeObject)); 230 if (!element) 231 return; 232 WebCore::HTMLInputElement* inputElement = element->toInputElement(); 233 if (!inputElement) 234 return; 235 236 inputElement->setValueForUser(value); 237} 238 239void DumpRenderTreeSupportEfl::setDefersLoading(Evas_Object* ewkView, bool defers) 240{ 241 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page); 242 243 page->setDefersLoading(defers); 244} 245 246void DumpRenderTreeSupportEfl::setLoadsSiteIconsIgnoringImageLoadingSetting(Evas_Object* ewkView, bool loadsSiteIconsIgnoringImageLoadingPreferences) 247{ 248 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page); 249 250 page->settings()->setLoadsSiteIconsIgnoringImageLoadingSetting(loadsSiteIconsIgnoringImageLoadingPreferences); 251} 252 253void DumpRenderTreeSupportEfl::setMinimumLogicalFontSize(Evas_Object* ewkView, int size) 254{ 255 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page); 256 257 page->settings()->setMinimumLogicalFontSize(size); 258} 259 260void DumpRenderTreeSupportEfl::addUserScript(const Evas_Object* ewkView, const String& sourceCode, bool runAtStart, bool allFrames) 261{ 262 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page); 263 264 page->group().addUserScriptToWorld(WebCore::mainThreadNormalWorld(), sourceCode, WebCore::KURL(), 265 Vector<String>(), Vector<String>(), runAtStart ? WebCore::InjectAtDocumentStart : WebCore::InjectAtDocumentEnd, 266 allFrames ? WebCore::InjectInAllFrames : WebCore::InjectInTopFrameOnly); 267} 268 269void DumpRenderTreeSupportEfl::clearUserScripts(const Evas_Object* ewkView) 270{ 271 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page); 272 273 page->group().removeUserScriptsFromWorld(WebCore::mainThreadNormalWorld()); 274} 275 276void DumpRenderTreeSupportEfl::addUserStyleSheet(const Evas_Object* ewkView, const String& sourceCode, bool allFrames) 277{ 278 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page); 279 280 page->group().addUserStyleSheetToWorld(WebCore::mainThreadNormalWorld(), sourceCode, WebCore::KURL(), Vector<String>(), Vector<String>(), allFrames ? WebCore::InjectInAllFrames : WebCore::InjectInTopFrameOnly); 281} 282 283void DumpRenderTreeSupportEfl::clearUserStyleSheets(const Evas_Object* ewkView) 284{ 285 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page); 286 287 page->group().removeUserStyleSheetsFromWorld(WebCore::mainThreadNormalWorld()); 288} 289 290void DumpRenderTreeSupportEfl::executeCoreCommandByName(const Evas_Object* ewkView, const char* name, const char* value) 291{ 292 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page); 293 294 page->focusController()->focusedOrMainFrame()->editor().command(name).execute(value); 295} 296 297bool DumpRenderTreeSupportEfl::findString(const Evas_Object* ewkView, const String& text, WebCore::FindOptions options) 298{ 299 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page, false); 300 301 return page->findString(text, options); 302} 303 304void DumpRenderTreeSupportEfl::setCSSGridLayoutEnabled(const Evas_Object* ewkView, bool enabled) 305{ 306 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page); 307 308 page->settings()->setCSSGridLayoutEnabled(enabled); 309} 310 311void DumpRenderTreeSupportEfl::setCSSRegionsEnabled(const Evas_Object* ewkView, bool enabled) 312{ 313 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page); 314 315 WebCore::RuntimeEnabledFeatures::setCSSRegionsEnabled(enabled); 316} 317 318void DumpRenderTreeSupportEfl::setSeamlessIFramesEnabled(bool enabled) 319{ 320#if ENABLE(IFRAME_SEAMLESS) 321 WebCore::RuntimeEnabledFeatures::setSeamlessIFramesEnabled(enabled); 322#else 323 UNUSED_PARAM(enabled); 324#endif 325} 326 327void DumpRenderTreeSupportEfl::setWebAudioEnabled(Evas_Object* ewkView, bool enabled) 328{ 329#if ENABLE(WEB_AUDIO) 330 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page); 331 332 page->settings()->setWebAudioEnabled(enabled); 333#else 334 UNUSED_PARAM(ewkView); 335 UNUSED_PARAM(enabled); 336#endif 337} 338 339bool DumpRenderTreeSupportEfl::isCommandEnabled(const Evas_Object* ewkView, const char* name) 340{ 341 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page, false); 342 343 return page->focusController()->focusedOrMainFrame()->editor().command(name).isEnabled(); 344} 345 346void DumpRenderTreeSupportEfl::forceLayout(Evas_Object* ewkFrame) 347{ 348 ewk_frame_force_layout(ewkFrame); 349} 350 351void DumpRenderTreeSupportEfl::setTracksRepaints(Evas_Object* ewkFrame, bool enabled) 352{ 353 DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame); 354 355 if (frame->view()) 356 frame->view()->setTracksRepaints(enabled); 357} 358 359void DumpRenderTreeSupportEfl::resetTrackedRepaints(Evas_Object* ewkFrame) 360{ 361 DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame); 362 363 if (frame->view()) 364 frame->view()->resetTrackedRepaints(); 365} 366 367bool DumpRenderTreeSupportEfl::isTrackingRepaints(const Evas_Object* ewkFrame) 368{ 369 DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, false); 370 371 if (!frame->view()) 372 return false; 373 374 return frame->view()->isTrackingRepaints(); 375} 376 377Eina_List* DumpRenderTreeSupportEfl::trackedRepaintRects(const Evas_Object* ewkFrame) 378{ 379 DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, 0); 380 381 if (!frame->view()) 382 return 0; 383 384 const Vector<WebCore::IntRect>& repaintRects = frame->view()->trackedRepaintRects(); 385 size_t count = repaintRects.size(); 386 Eina_List* rectList = 0; 387 388 for (size_t i = 0; i < count; ++i) { 389 Eina_Rectangle* rect = eina_rectangle_new(repaintRects[i].x(), repaintRects[i].y(), repaintRects[i].width(), repaintRects[i].height()); 390 rectList = eina_list_append(rectList, rect); 391 } 392 393 return rectList; 394} 395 396void DumpRenderTreeSupportEfl::garbageCollectorCollect() 397{ 398 WebCore::gcController().garbageCollectNow(); 399} 400 401void DumpRenderTreeSupportEfl::garbageCollectorCollectOnAlternateThread(bool waitUntilDone) 402{ 403 WebCore::gcController().garbageCollectOnAlternateThreadForDebugging(waitUntilDone); 404} 405 406size_t DumpRenderTreeSupportEfl::javaScriptObjectsCount() 407{ 408 return WebCore::JSDOMWindow::commonVM()->heap.objectCount(); 409} 410 411void DumpRenderTreeSupportEfl::setDeadDecodedDataDeletionInterval(double interval) 412{ 413 WebCore::memoryCache()->setDeadDecodedDataDeletionInterval(interval); 414} 415 416HistoryItemChildrenVector DumpRenderTreeSupportEfl::childHistoryItems(const Ewk_History_Item* ewkHistoryItem) 417{ 418 WebCore::HistoryItem* historyItem = EWKPrivate::coreHistoryItem(ewkHistoryItem); 419 HistoryItemChildrenVector kids; 420 421 if (!historyItem) 422 return kids; 423 424 const WebCore::HistoryItemVector& children = historyItem->children(); 425 const unsigned size = children.size(); 426 427 for (unsigned i = 0; i < size; ++i) { 428 Ewk_History_Item* kid = ewk_history_item_new_from_core(children[i].get()); 429 kids.append(kid); 430 } 431 432 return kids; 433} 434 435String DumpRenderTreeSupportEfl::historyItemTarget(const Ewk_History_Item* ewkHistoryItem) 436{ 437 WebCore::HistoryItem* historyItem = EWKPrivate::coreHistoryItem(ewkHistoryItem); 438 439 if (!historyItem) 440 return String(); 441 442 return historyItem->target(); 443} 444 445bool DumpRenderTreeSupportEfl::isTargetItem(const Ewk_History_Item* ewkHistoryItem) 446{ 447 WebCore::HistoryItem* historyItem = EWKPrivate::coreHistoryItem(ewkHistoryItem); 448 449 if (!historyItem) 450 return false; 451 452 return historyItem->isTargetItem(); 453} 454 455void DumpRenderTreeSupportEfl::evaluateInWebInspector(const Evas_Object* ewkView, long callId, const String& script) 456{ 457#if ENABLE(INSPECTOR) 458 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page); 459 460 if (page->inspectorController()) 461 page->inspectorController()->evaluateForTestInFrontend(callId, script); 462#else 463 UNUSED_PARAM(ewkView); 464 UNUSED_PARAM(callId); 465 UNUSED_PARAM(script); 466#endif 467} 468 469void DumpRenderTreeSupportEfl::evaluateScriptInIsolatedWorld(const Evas_Object* ewkFrame, int worldID, JSObjectRef globalObject, const String& script) 470{ 471 DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame); 472 473 // Comment from mac: Start off with some guess at a frame and a global object, we'll try to do better...! 474 WebCore::JSDOMWindow* anyWorldGlobalObject = frame->script()->globalObject(WebCore::mainThreadNormalWorld()); 475 476 // Comment from mac: The global object is probably a shell object? - if so, we know how to use this! 477 JSC::JSObject* globalObjectObj = toJS(globalObject); 478 if (!strcmp(globalObjectObj->classInfo()->className, "JSDOMWindowShell")) 479 anyWorldGlobalObject = static_cast<WebCore::JSDOMWindowShell*>(globalObjectObj)->window(); 480 481 // Comment from mac: Get the frame from the global object we've settled on. 482 WebCore::Frame* globalFrame = anyWorldGlobalObject->impl()->frame(); 483 if (!globalFrame) 484 return; 485 486 WebCore::ScriptController* proxy = globalFrame->script(); 487 if (!proxy) 488 return; 489 490 static WTF::HashMap<int, WTF::RefPtr<WebCore::DOMWrapperWorld > > worldMap; 491 492 WTF::RefPtr<WebCore::DOMWrapperWorld> scriptWorld; 493 if (!worldID) 494 scriptWorld = WebCore::ScriptController::createWorld(); 495 else { 496 WTF::HashMap<int, RefPtr<WebCore::DOMWrapperWorld > >::const_iterator it = worldMap.find(worldID); 497 if (it != worldMap.end()) 498 scriptWorld = (*it).value; 499 else { 500 scriptWorld = WebCore::ScriptController::createWorld(); 501 worldMap.set(worldID, scriptWorld); 502 } 503 } 504 505 // The code below is only valid for JSC, V8 specific code is to be added 506 // when V8 will be supported in EFL port. See Qt implemenation. 507 proxy->executeScriptInWorld(scriptWorld.get(), script, true); 508} 509 510JSGlobalContextRef DumpRenderTreeSupportEfl::globalContextRefForFrame(const Evas_Object* ewkFrame) 511{ 512 DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, 0); 513 514 return toGlobalRef(frame->script()->globalObject(WebCore::mainThreadNormalWorld())->globalExec()); 515} 516 517void DumpRenderTreeSupportEfl::setMockScrollbarsEnabled(bool enable) 518{ 519 WebCore::Settings::setMockScrollbarsEnabled(enable); 520} 521 522void DumpRenderTreeSupportEfl::deliverAllMutationsIfNecessary() 523{ 524 WebCore::MutationObserver::deliverAllMutations(); 525} 526 527void DumpRenderTreeSupportEfl::setInteractiveFormValidationEnabled(Evas_Object* ewkView, bool enabled) 528{ 529 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page); 530 531 page->settings()->setInteractiveFormValidationEnabled(enabled); 532} 533 534void DumpRenderTreeSupportEfl::setValidationMessageTimerMagnification(Evas_Object* ewkView, int value) 535{ 536 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page); 537 538 page->settings()->setValidationMessageTimerMagnification(value); 539} 540 541void DumpRenderTreeSupportEfl::setAuthorAndUserStylesEnabled(Evas_Object* ewkView, bool enabled) 542{ 543 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page); 544 545 page->settings()->setAuthorAndUserStylesEnabled(enabled); 546} 547 548void DumpRenderTreeSupportEfl::setSerializeHTTPLoads(bool enabled) 549{ 550 WebCore::resourceLoadScheduler()->setSerialLoadingEnabled(enabled); 551} 552 553void DumpRenderTreeSupportEfl::setShouldTrackVisitedLinks(bool shouldTrack) 554{ 555 WebCore::PageGroup::setShouldTrackVisitedLinks(shouldTrack); 556} 557 558void DumpRenderTreeSupportEfl::setComposition(Evas_Object* ewkView, const char* text, int start, int length) 559{ 560 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page); 561 562 if (!page->focusController() || !page->focusController()->focusedOrMainFrame()) 563 return; 564 565 WebCore::Editor& editor = page->focusController()->focusedOrMainFrame()->editor(); 566 if (!editor.canEdit() && !editor.hasComposition()) 567 return; 568 569 const String compositionString = String::fromUTF8(text); 570 Vector<WebCore::CompositionUnderline> underlines; 571 underlines.append(WebCore::CompositionUnderline(0, compositionString.length(), WebCore::Color(0, 0, 0), false)); 572 editor.setComposition(compositionString, underlines, start, start + length); 573} 574 575bool DumpRenderTreeSupportEfl::hasComposition(const Evas_Object* ewkView) 576{ 577 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page, false); 578 579 if (!page->focusController() || !page->focusController()->focusedOrMainFrame()) 580 return false; 581 582 return page->focusController()->focusedOrMainFrame()->editor().hasComposition(); 583} 584 585bool DumpRenderTreeSupportEfl::compositionRange(Evas_Object* ewkView, int* start, int* length) 586{ 587 *start = *length = 0; 588 589 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page, false); 590 591 if (!page->focusController() || !page->focusController()->focusedOrMainFrame()) 592 return false; 593 594 WebCore::Editor& editor = page->focusController()->focusedOrMainFrame()->editor(); 595 if (!editor.hasComposition()) 596 return false; 597 598 *start = editor.compositionStart(); 599 *length = editor.compositionEnd() - *start; 600 return true; 601} 602 603void DumpRenderTreeSupportEfl::confirmComposition(Evas_Object* ewkView, const char* text) 604{ 605 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page); 606 607 if (!page->focusController() || !page->focusController()->focusedOrMainFrame()) 608 return; 609 610 WebCore::Editor& editor = page->focusController()->focusedOrMainFrame()->editor(); 611 612 if (!editor.hasComposition()) { 613 editor.insertText(String::fromUTF8(text), 0); 614 return; 615 } 616 617 if (text) { 618 editor.confirmComposition(String::fromUTF8(text)); 619 return; 620 } 621 editor.confirmComposition(); 622} 623 624WebCore::IntRect DumpRenderTreeSupportEfl::firstRectForCharacterRange(Evas_Object* ewkView, int location, int length) 625{ 626 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page, WebCore::IntRect()); 627 628 if (!page->focusController() || !page->focusController()->focusedOrMainFrame()) 629 return WebCore::IntRect(); 630 631 if ((location + length < location) && (location + length)) 632 length = 0; 633 634 WebCore::Frame* frame = page->focusController()->focusedOrMainFrame(); 635 636 RefPtr<WebCore::Range> range = WebCore::TextIterator::rangeFromLocationAndLength(frame->selection()->rootEditableElementOrDocumentElement(), location, length); 637 if (!range) 638 return WebCore::IntRect(); 639 640 return frame->editor().firstRectForRange(range.get()); 641} 642 643bool DumpRenderTreeSupportEfl::selectedRange(Evas_Object* ewkView, int* start, int* length) 644{ 645 if (!(start && length)) 646 return false; 647 648 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page, false); 649 650 if (!page->focusController() || !page->focusController()->focusedOrMainFrame()) 651 return false; 652 653 WebCore::Frame* frame = page->focusController()->focusedOrMainFrame(); 654 RefPtr<WebCore::Range> range = frame->selection()->toNormalizedRange().get(); 655 if (!range) 656 return false; 657 658 WebCore::Element* selectionRoot = frame->selection()->rootEditableElement(); 659 WebCore::Element* scope = selectionRoot ? selectionRoot : frame->document()->documentElement(); 660 661 RefPtr<WebCore::Range> testRange = WebCore::Range::create(scope->document(), scope, 0, range->startContainer(), range->startOffset()); 662 *start = WebCore::TextIterator::rangeLength(testRange.get()); 663 664 WebCore::ExceptionCode ec; 665 testRange->setEnd(range->endContainer(), range->endOffset(), ec); 666 *length = WebCore::TextIterator::rangeLength(testRange.get()); 667 668 return true; 669} 670 671void DumpRenderTreeSupportEfl::setDomainRelaxationForbiddenForURLScheme(bool forbidden, const String& scheme) 672{ 673 WebCore::SchemeRegistry::setDomainRelaxationForbiddenForURLScheme(forbidden, scheme); 674} 675 676void DumpRenderTreeSupportEfl::resetGeolocationClientMock(const Evas_Object* ewkView) 677{ 678#if ENABLE(GEOLOCATION) 679 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page); 680 681 WebCore::GeolocationClientMock* mock = static_cast<WebCore::GeolocationClientMock*>(WebCore::GeolocationController::from(page)->client()); 682 mock->reset(); 683#else 684 UNUSED_PARAM(ewkView); 685#endif 686} 687 688void DumpRenderTreeSupportEfl::setMockGeolocationPermission(const Evas_Object* ewkView, bool allowed) 689{ 690#if ENABLE(GEOLOCATION) 691 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page); 692 693 WebCore::GeolocationClientMock* mock = static_cast<WebCore::GeolocationClientMock*>(WebCore::GeolocationController::from(page)->client()); 694 mock->setPermission(allowed); 695#else 696 UNUSED_PARAM(ewkView); 697 UNUSED_PARAM(allowed); 698#endif 699} 700 701void DumpRenderTreeSupportEfl::setMockGeolocationPosition(const Evas_Object* ewkView, double latitude, double longitude, double accuracy, bool canProvideAltitude, double altitude, bool canProvideAltitudeAccuracy, double altitudeAccuracy, bool canProvideHeading, double heading, bool canProvideSpeed, double speed) 702{ 703#if ENABLE(GEOLOCATION) 704 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page); 705 706 WebCore::GeolocationClientMock* mock = static_cast<WebCore::GeolocationClientMock*>(WebCore::GeolocationController::from(page)->client()); 707 mock->setPosition(WebCore::GeolocationPosition::create(currentTime(), latitude, longitude, accuracy, canProvideAltitude, altitude, canProvideAltitudeAccuracy, altitudeAccuracy, canProvideHeading, heading, canProvideSpeed, speed)); 708#else 709 UNUSED_PARAM(ewkView); 710 UNUSED_PARAM(latitude); 711 UNUSED_PARAM(longitude); 712 UNUSED_PARAM(accuracy); 713 UNUSED_PARAM(canProvideAltitude); 714 UNUSED_PARAM(altitude); 715 UNUSED_PARAM(canProvideAltitudeAccuracy); 716 UNUSED_PARAM(altitudeAccuracy); 717 UNUSED_PARAM(canProvideHeading); 718 UNUSED_PARAM(heading); 719 UNUSED_PARAM(canProvideSpeed); 720 UNUSED_PARAM(speed); 721#endif 722} 723 724void DumpRenderTreeSupportEfl::setMockGeolocationPositionUnavailableError(const Evas_Object* ewkView, const char* errorMessage) 725{ 726#if ENABLE(GEOLOCATION) 727 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page); 728 729 WebCore::GeolocationClientMock* mock = static_cast<WebCore::GeolocationClientMock*>(WebCore::GeolocationController::from(page)->client()); 730 mock->setPositionUnavailableError(errorMessage); 731#else 732 UNUSED_PARAM(ewkView); 733 UNUSED_PARAM(errorMessage); 734#endif 735} 736 737int DumpRenderTreeSupportEfl::numberOfPendingGeolocationPermissionRequests(const Evas_Object* ewkView) 738{ 739#if ENABLE(GEOLOCATION) 740 DRT_SUPPRT_PAGE_GET_OR_RETURN(ewkView, page, -1); 741 742 WebCore::GeolocationClientMock* mock = static_cast<WebCore::GeolocationClientMock*>(WebCore::GeolocationController::from(page)->client()); 743 return mock->numberOfPendingPermissionRequests(); 744#else 745 UNUSED_PARAM(ewkView); 746 return 0; 747#endif 748} 749 750#if HAVE(ACCESSIBILITY) 751String DumpRenderTreeSupportEfl::accessibilityHelpText(const AtkObject* axObject) 752{ 753 if (!axObject || !WEBKIT_IS_ACCESSIBLE(axObject)) 754 return String(); 755 756 WebCore::AccessibilityObject* coreObject = webkitAccessibleGetAccessibilityObject(WEBKIT_ACCESSIBLE(axObject)); 757 if (!coreObject) 758 return String(); 759 760 return coreObject->helpText(); 761} 762 763AtkObject* DumpRenderTreeSupportEfl::rootAccessibleElement(const Evas_Object* ewkFrame) 764{ 765 DRT_SUPPORT_FRAME_GET_OR_RETURN(ewkFrame, frame, 0); 766 767 if (!WebCore::AXObjectCache::accessibilityEnabled()) 768 WebCore::AXObjectCache::enableAccessibility(); 769 770 if (!frame->document()) 771 return 0; 772 773 AtkObject* wrapper = frame->document()->axObjectCache()->rootObject()->wrapper(); 774 if (!wrapper) 775 return 0; 776 777 return wrapper; 778} 779 780AtkObject* DumpRenderTreeSupportEfl::focusedAccessibleElement(const Evas_Object* ewkFrame) 781{ 782 AtkObject* wrapper = rootAccessibleElement(ewkFrame); 783 if (!wrapper) 784 return 0; 785 786 return webkitAccessibleGetFocusedElement(WEBKIT_ACCESSIBLE(wrapper)); 787} 788#endif 789