OSDN Git Service

Merge Webkit at r70949: Initial merge by git.
[android-x86/external-webkit.git] / WebKitTools / WebKitTestRunner / InjectedBundle / LayoutTestController.cpp
index fafa1e3..e828c46 100644 (file)
 #include "InjectedBundle.h"
 #include "InjectedBundlePage.h"
 #include "JSLayoutTestController.h"
-#include <JavaScriptCore/JSRetainPtr.h>
+#include "StringFunctions.h"
+#include <WebKit2/WKBundleBackForwardList.h>
 #include <WebKit2/WKBundleFrame.h>
+#include <WebKit2/WKBundleFramePrivate.h>
+#include <WebKit2/WKBundlePagePrivate.h>
+#include <WebKit2/WKBundleScriptWorld.h>
+#include <WebKit2/WKBundlePrivate.h>
 #include <WebKit2/WKRetainPtr.h>
-#include <WebKit2/WKStringCF.h>
 #include <WebKit2/WebKit2.h>
 
 namespace WTR {
 
-PassRefPtr<LayoutTestController> LayoutTestController::create(const std::string& testPathOrURL)
+// This is lower than DumpRenderTree's timeout, to make it easier to work through the failures
+// Eventually it should be changed to match.
+const double LayoutTestController::waitToDumpWatchdogTimerInterval = 6;
+
+static JSValueRef propertyValue(JSContextRef context, JSObjectRef object, const char* propertyName)
+{
+    if (!object)
+        return 0;
+    JSRetainPtr<JSStringRef> propertyNameString(Adopt, JSStringCreateWithUTF8CString(propertyName));
+    JSValueRef exception;
+    return JSObjectGetProperty(context, object, propertyNameString.get(), &exception);
+}
+
+static JSObjectRef propertyObject(JSContextRef context, JSObjectRef object, const char* propertyName)
+{
+    JSValueRef value = propertyValue(context, object, propertyName);
+    if (!value || !JSValueIsObject(context, value))
+        return 0;
+    return const_cast<JSObjectRef>(value);
+}
+
+static JSObjectRef getElementById(WKBundleFrameRef frame, JSStringRef elementId)
 {
-    return adoptRef(new LayoutTestController(testPathOrURL));
+    JSContextRef context = WKBundleFrameGetJavaScriptContext(frame);
+    JSObjectRef document = propertyObject(context, JSContextGetGlobalObject(context), "document");
+    if (!document)
+        return 0;
+    JSValueRef getElementById = propertyObject(context, document, "getElementById");
+    if (!getElementById || !JSValueIsObject(context, getElementById))
+        return 0;
+    JSValueRef elementIdValue = JSValueMakeString(context, elementId);
+    JSValueRef exception;
+    JSValueRef element = JSObjectCallAsFunction(context, const_cast<JSObjectRef>(getElementById), document, 1, &elementIdValue, &exception);
+    if (!element || !JSValueIsObject(context, element))
+        return 0;
+    return const_cast<JSObjectRef>(element);
 }
 
-LayoutTestController::LayoutTestController(const std::string& testPathOrURL)
-    : m_dumpAsText(false)
+PassRefPtr<LayoutTestController> LayoutTestController::create()
+{
+    return adoptRef(new LayoutTestController);
+}
+
+LayoutTestController::LayoutTestController()
+    : m_whatToDump(RenderTree)
+    , m_shouldDumpAllFrameScrollPositions(false)
+    , m_shouldDumpBackForwardListsForAllWindows(false)
+    , m_shouldAllowEditing(true)
+    , m_shouldCloseExtraWindows(false)
+    , m_dumpEditingCallbacks(false)
     , m_dumpStatusCallbacks(false)
+    , m_dumpTitleChanges(false)
     , m_waitToDump(false)
     , m_testRepaint(false)
     , m_testRepaintSweepHorizontally(false)
-    , m_testPathOrURL(testPathOrURL)
 {
+    platformInitialize();
 }
 
 LayoutTestController::~LayoutTestController()
@@ -60,41 +108,20 @@ JSClassRef LayoutTestController::wrapperClass()
     return JSLayoutTestController::layoutTestControllerClass();
 }
 
-// This is lower than DumpRenderTree's timeout, to make it easier to work through the failures
-// Eventually it should be changed to match.
-static const CFTimeInterval waitToDumpWatchdogInterval = 6.0;
-
 void LayoutTestController::display()
 {
     // FIXME: actually implement, once we want pixel tests
 }
 
-void LayoutTestController::invalidateWaitToDumpWatchdog()
-{
-    if (m_waitToDumpWatchdog) {
-        CFRunLoopTimerInvalidate(m_waitToDumpWatchdog.get());
-        m_waitToDumpWatchdog = 0;
-    }
-}
-
-static void waitUntilDoneWatchdogFired(CFRunLoopTimerRef timer, void* info)
-{
-    InjectedBundle::shared().layoutTestController()->waitToDumpWatchdogTimerFired();
-}
-
 void LayoutTestController::waitUntilDone()
 {
     m_waitToDump = true;
-    if (!m_waitToDumpWatchdog) {
-        m_waitToDumpWatchdog.adoptCF(CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + waitToDumpWatchdogInterval, 
-                                                      0, 0, 0, waitUntilDoneWatchdogFired, NULL));
-        CFRunLoopAddTimer(CFRunLoopGetCurrent(), m_waitToDumpWatchdog.get(), kCFRunLoopCommonModes);
-    }
+    initializeWaitToDumpWatchdogTimerIfNeeded();
 }
 
 void LayoutTestController::waitToDumpWatchdogTimerFired()
 {
-    invalidateWaitToDumpWatchdog();
+    invalidateWaitToDumpWatchdogTimer();
     const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
     InjectedBundle::shared().os() << message << "\n";
     InjectedBundle::shared().done();
@@ -109,27 +136,122 @@ void LayoutTestController::notifyDone()
 
 unsigned LayoutTestController::numberOfActiveAnimations() const
 {
+    // FIXME: Is it OK this works only for the main frame?
+    // FIXME: If this is needed only for the main frame, then why is the function on WKBundleFrame instead of WKBundlePage?
     WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
     return WKBundleFrameGetNumberOfActiveAnimations(mainFrame);
 }
 
 bool LayoutTestController::pauseAnimationAtTimeOnElementWithId(JSStringRef animationName, double time, JSStringRef elementId)
 {
-    RetainPtr<CFStringRef> idCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, elementId));
-    WKRetainPtr<WKStringRef> idWK(AdoptWK, WKStringCreateWithCFString(idCF.get()));
-    RetainPtr<CFStringRef> nameCF(AdoptCF, JSStringCopyCFString(kCFAllocatorDefault, animationName));
-    WKRetainPtr<WKStringRef> nameWK(AdoptWK, WKStringCreateWithCFString(nameCF.get()));
+    // FIXME: Is it OK this works only for the main frame?
+    // FIXME: If this is needed only for the main frame, then why is the function on WKBundleFrame instead of WKBundlePage?
+    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
+    return WKBundleFramePauseAnimationOnElementWithId(mainFrame, toWK(animationName).get(), toWK(elementId).get(), time);
+}
 
+JSRetainPtr<JSStringRef> LayoutTestController::layerTreeAsText() const
+{
     WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
-    return WKBundleFramePauseAnimationOnElementWithId(mainFrame, nameWK.get(), idWK.get(), time);
+    WKRetainPtr<WKStringRef> text(AdoptWK, WKBundleFrameCopyLayerTreeAsText(mainFrame));
+    return toJS(text);
+}
+
+void LayoutTestController::addUserScript(JSStringRef source, bool runAtStart, bool allFrames)
+{
+    WKRetainPtr<WKStringRef> sourceWK = toWK(source);
+    WKRetainPtr<WKBundleScriptWorldRef> scriptWorld(AdoptWK, WKBundleScriptWorldCreateWorld());
+
+    WKBundleAddUserScript(InjectedBundle::shared().bundle(), scriptWorld.get(), sourceWK.get(), 0, 0, 0,
+        (runAtStart ? kWKInjectAtDocumentStart : kWKInjectAtDocumentEnd),
+        (allFrames ? kWKInjectInAllFrames : kWKInjectInTopFrameOnly));
+}
+
+void LayoutTestController::addUserStyleSheet(JSStringRef source, bool allFrames)
+{
+    WKRetainPtr<WKStringRef> sourceWK = toWK(source);
+    WKRetainPtr<WKBundleScriptWorldRef> scriptWorld(AdoptWK, WKBundleScriptWorldCreateWorld());
+
+    WKBundleAddUserStyleSheet(InjectedBundle::shared().bundle(), scriptWorld.get(), sourceWK.get(), 0, 0, 0,
+        (allFrames ? kWKInjectInAllFrames : kWKInjectInTopFrameOnly));
+}
+
+void LayoutTestController::keepWebHistory()
+{
+    WKBundleSetShouldTrackVisitedLinks(InjectedBundle::shared().bundle(), true);
+}
+
+JSValueRef LayoutTestController::computedStyleIncludingVisitedInfo(JSValueRef element)
+{
+    // FIXME: Is it OK this works only for the main frame?
+    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
+    JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
+    if (!JSValueIsObject(context, element))
+        return JSValueMakeUndefined(context);
+    JSValueRef value = WKBundleFrameGetComputedStyleIncludingVisitedInfo(mainFrame, const_cast<JSObjectRef>(element));
+    if (!value)
+        return JSValueMakeUndefined(context);
+    return value;
+}
+
+JSRetainPtr<JSStringRef> LayoutTestController::counterValueForElementById(JSStringRef elementId)
+{
+    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
+    JSObjectRef element = getElementById(mainFrame, elementId);
+    if (!element)
+        return 0;
+    WKRetainPtr<WKStringRef> value(AdoptWK, WKBundleFrameCopyCounterValue(mainFrame, const_cast<JSObjectRef>(element)));
+    return toJS(value);
+}
+
+JSRetainPtr<JSStringRef> LayoutTestController::markerTextForListItem(JSValueRef element)
+{
+    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
+    JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame);
+    if (!element || !JSValueIsObject(context, element))
+        return 0;
+    WKRetainPtr<WKStringRef> text(AdoptWK, WKBundleFrameCopyMarkerText(mainFrame, const_cast<JSObjectRef>(element)));
+    if (WKStringIsEmpty(text.get()))
+        return 0;
+    return toJS(text);
+}
+
+void LayoutTestController::execCommand(JSStringRef name, JSStringRef argument)
+{
+    WKBundlePageExecuteEditingCommand(InjectedBundle::shared().page()->page(), toWK(name).get(), toWK(argument).get());
+}
+
+bool LayoutTestController::isCommandEnabled(JSStringRef name)
+{
+    return WKBundlePageIsEditingCommandEnabled(InjectedBundle::shared().page()->page(), toWK(name).get());
+}
+
+void LayoutTestController::setCanOpenWindows(bool)
+{
+    // It's not clear if or why any tests require opening windows be forbidden.
+    // For now, just ignore this setting, and if we find later it's needed we can add it.
+}
+
+void LayoutTestController::setXSSAuditorEnabled(bool enabled)
+{
+    WKBundleOverrideXSSAuditorEnabledForTestRunner(InjectedBundle::shared().bundle(), true);
+}
+
+unsigned LayoutTestController::windowCount()
+{
+    return InjectedBundle::shared().pageCount();
+}
+
+void LayoutTestController::clearBackForwardList()
+{
+    WKBundleBackForwardListClear(WKBundlePageGetBackForwardList(InjectedBundle::shared().page()->page()));
 }
 
 // Object Creation
 
 void LayoutTestController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
 {
-    JSRetainPtr<JSStringRef> layoutTestContollerStr(Adopt, JSStringCreateWithUTF8CString("layoutTestController"));
-    JSObjectSetProperty(context, windowObject, layoutTestContollerStr.get(), JSWrapper::wrap(context, this), kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
+    setProperty(context, windowObject, "layoutTestController", this, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
 }
 
 } // namespace WTR