OSDN Git Service

Merge Webkit at r70949: Initial merge by git.
[android-x86/external-webkit.git] / WebKitTools / WebKitTestRunner / InjectedBundle / LayoutTestController.cpp
index 014851c..e828c46 100644 (file)
 
 #include "LayoutTestController.h"
 
-#include <JavaScriptCore/JSRetainPtr.h>
+#include "InjectedBundle.h"
+#include "InjectedBundlePage.h"
+#include "JSLayoutTestController.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/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)
 {
-    return adoptRef(new LayoutTestController(testPathOrURL));
+    JSValueRef value = propertyValue(context, object, propertyName);
+    if (!value || !JSValueIsObject(context, value))
+        return 0;
+    return const_cast<JSObjectRef>(value);
 }
 
-LayoutTestController::LayoutTestController(const std::string& testPathOrURL)
-    : m_dumpAsText(false)
-    , m_testPathOrURL(testPathOrURL)
+static JSObjectRef getElementById(WKBundleFrameRef frame, JSStringRef elementId)
 {
+    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);
+}
+
+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)
+{
+    platformInitialize();
 }
 
 LayoutTestController::~LayoutTestController()
 {
 }
 
-static JSValueRef dumpAsTextCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+JSClassRef LayoutTestController::wrapperClass()
 {
-    LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
-    controller->setDumpAsText(true);
-    return JSValueMakeUndefined(context);
+    return JSLayoutTestController::layoutTestControllerClass();
 }
 
-// Object Finalization
+void LayoutTestController::display()
+{
+    // FIXME: actually implement, once we want pixel tests
+}
 
-static void layoutTestControllerObjectFinalize(JSObjectRef object)
+void LayoutTestController::waitUntilDone()
 {
-    LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(object));
-    controller->deref();
+    m_waitToDump = true;
+    initializeWaitToDumpWatchdogTimerIfNeeded();
 }
 
-// Object Creation
+void LayoutTestController::waitToDumpWatchdogTimerFired()
+{
+    invalidateWaitToDumpWatchdogTimer();
+    const char* message = "FAIL: Timed out waiting for notifyDone to be called\n";
+    InjectedBundle::shared().os() << message << "\n";
+    InjectedBundle::shared().done();
+}
 
-void LayoutTestController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception)
+void LayoutTestController::notifyDone()
+{
+    if (m_waitToDump && !InjectedBundle::shared().page()->isLoading())
+        InjectedBundle::shared().page()->dump();
+    m_waitToDump = false;
+}
+
+unsigned LayoutTestController::numberOfActiveAnimations() const
 {
-    JSRetainPtr<JSStringRef> layoutTestContollerStr(Adopt, JSStringCreateWithUTF8CString("layoutTestController"));
-    ref();
+    // 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);
+}
 
-    JSClassRef classRef = getJSClass();
-    JSValueRef layoutTestContollerObject = JSObjectMake(context, classRef, this);
-    JSClassRelease(classRef);
+bool LayoutTestController::pauseAnimationAtTimeOnElementWithId(JSStringRef animationName, double time, JSStringRef elementId)
+{
+    // 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);
+}
 
-    JSObjectSetProperty(context, windowObject, layoutTestContollerStr.get(), layoutTestContollerObject, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
+JSRetainPtr<JSStringRef> LayoutTestController::layerTreeAsText() const
+{
+    WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page());
+    WKRetainPtr<WKStringRef> text(AdoptWK, WKBundleFrameCopyLayerTreeAsText(mainFrame));
+    return toJS(text);
 }
 
-JSClassRef LayoutTestController::getJSClass()
+void LayoutTestController::addUserScript(JSStringRef source, bool runAtStart, bool allFrames)
 {
-    static JSStaticFunction* staticFunctions = LayoutTestController::staticFunctions();
-    static JSClassDefinition classDefinition = {
-        0, kJSClassAttributeNone, "LayoutTestController", 0, 0, staticFunctions,
-        0, layoutTestControllerObjectFinalize, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    };
+    WKRetainPtr<WKStringRef> sourceWK = toWK(source);
+    WKRetainPtr<WKBundleScriptWorldRef> scriptWorld(AdoptWK, WKBundleScriptWorldCreateWorld());
 
-    return JSClassCreate(&classDefinition);
+    WKBundleAddUserScript(InjectedBundle::shared().bundle(), scriptWorld.get(), sourceWK.get(), 0, 0, 0,
+        (runAtStart ? kWKInjectAtDocumentStart : kWKInjectAtDocumentEnd),
+        (allFrames ? kWKInjectInAllFrames : kWKInjectInTopFrameOnly));
 }
 
-JSStaticFunction* LayoutTestController::staticFunctions()
+void LayoutTestController::addUserStyleSheet(JSStringRef source, bool allFrames)
 {
-    static JSStaticFunction staticFunctions[] = {
-        { "dumpAsText", dumpAsTextCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
-        { 0, 0, 0 }
-    };
+    WKRetainPtr<WKStringRef> sourceWK = toWK(source);
+    WKRetainPtr<WKBundleScriptWorldRef> scriptWorld(AdoptWK, WKBundleScriptWorldCreateWorld());
 
-    return staticFunctions;
+    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)
+{
+    setProperty(context, windowObject, "layoutTestController", this, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception);
 }
 
 } // namespace WTR