LayoutTestController.cpp revision ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddb
1ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block/* 2ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * Copyright (C) 2010 Apple Inc. All rights reserved. 3ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * 4ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * Redistribution and use in source and binary forms, with or without 5ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * modification, are permitted provided that the following conditions 6ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * are met: 7ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * 1. Redistributions of source code must retain the above copyright 8ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * notice, this list of conditions and the following disclaimer. 9ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * 2. Redistributions in binary form must reproduce the above copyright 10ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * notice, this list of conditions and the following disclaimer in the 11ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * documentation and/or other materials provided with the distribution. 12ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * 13ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block * THE POSSIBILITY OF SUCH DAMAGE. 24ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block */ 25ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 26ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include "LayoutTestController.h" 27967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 28e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "InjectedBundle.h" 29e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include "InjectedBundlePage.h" 30967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#include "JSLayoutTestController.h" 31dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include "StringFunctions.h" 32e14391e94c850b8bd03680c23b38978db68687a8John Reck#include <WebKit2/WKBundleBackForwardList.h> 33e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include <WebKit2/WKBundleFrame.h> 340617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen#include <WebKit2/WKBundleFramePrivate.h> 350617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen#include <WebKit2/WKBundlePagePrivate.h> 365ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include <WebKit2/WKBundleScriptWorld.h> 37dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include <WebKit2/WKBundlePrivate.h> 38e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include <WebKit2/WKRetainPtr.h> 39e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include <WebKit2/WebKit2.h> 40ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include <wtf/HashMap.h> 41ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 42ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blocknamespace WTR { 43ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 440617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen// This is lower than DumpRenderTree's timeout, to make it easier to work through the failures 450617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen// Eventually it should be changed to match. 4668513a70bcd92384395513322f1b801e7bf9c729Steve Blockconst double LayoutTestController::waitToDumpWatchdogTimerInterval = 6; 470617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen 480617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenstatic JSValueRef propertyValue(JSContextRef context, JSObjectRef object, const char* propertyName) 490617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{ 500617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen if (!object) 510617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen return 0; 520617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen JSRetainPtr<JSStringRef> propertyNameString(Adopt, JSStringCreateWithUTF8CString(propertyName)); 530617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen JSValueRef exception; 540617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen return JSObjectGetProperty(context, object, propertyNameString.get(), &exception); 550617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen} 560617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen 570617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenstatic JSObjectRef propertyObject(JSContextRef context, JSObjectRef object, const char* propertyName) 580617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{ 590617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen JSValueRef value = propertyValue(context, object, propertyName); 600617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen if (!value || !JSValueIsObject(context, value)) 610617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen return 0; 620617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen return const_cast<JSObjectRef>(value); 630617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen} 640617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen 650617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenstatic JSObjectRef getElementById(WKBundleFrameRef frame, JSStringRef elementId) 66ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{ 670617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen JSContextRef context = WKBundleFrameGetJavaScriptContext(frame); 680617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen JSObjectRef document = propertyObject(context, JSContextGetGlobalObject(context), "document"); 690617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen if (!document) 700617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen return 0; 710617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen JSValueRef getElementById = propertyObject(context, document, "getElementById"); 720617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen if (!getElementById || !JSValueIsObject(context, getElementById)) 730617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen return 0; 740617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen JSValueRef elementIdValue = JSValueMakeString(context, elementId); 750617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen JSValueRef exception; 760617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen JSValueRef element = JSObjectCallAsFunction(context, const_cast<JSObjectRef>(getElementById), document, 1, &elementIdValue, &exception); 770617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen if (!element || !JSValueIsObject(context, element)) 780617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen return 0; 790617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen return const_cast<JSObjectRef>(element); 80ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block} 81ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 820617145a89917ae7735fe1c9538688ab9a577df5Kristian MonsenPassRefPtr<LayoutTestController> LayoutTestController::create() 830617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{ 840617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen return adoptRef(new LayoutTestController); 850617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen} 860617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen 870617145a89917ae7735fe1c9538688ab9a577df5Kristian MonsenLayoutTestController::LayoutTestController() 880617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen : m_whatToDump(RenderTree) 890617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen , m_shouldDumpAllFrameScrollPositions(false) 90e14391e94c850b8bd03680c23b38978db68687a8John Reck , m_shouldDumpBackForwardListsForAllWindows(false) 910617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen , m_shouldAllowEditing(true) 92db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block , m_shouldCloseExtraWindows(false) 930617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen , m_dumpEditingCallbacks(false) 94967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch , m_dumpStatusCallbacks(false) 95dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch , m_dumpTitleChanges(false) 96e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke , m_waitToDump(false) 97967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch , m_testRepaint(false) 98967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch , m_testRepaintSweepHorizontally(false) 99ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{ 10068513a70bcd92384395513322f1b801e7bf9c729Steve Block platformInitialize(); 101ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block} 102ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 103ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve BlockLayoutTestController::~LayoutTestController() 104ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{ 105ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block} 106ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 107967717af5423377c967781471ee106e2bb4e11c8Ben MurdochJSClassRef LayoutTestController::wrapperClass() 108967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 109967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return JSLayoutTestController::layoutTestControllerClass(); 110967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 111e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 112967717af5423377c967781471ee106e2bb4e11c8Ben Murdochvoid LayoutTestController::display() 113967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 114967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch // FIXME: actually implement, once we want pixel tests 115967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 116e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 117967717af5423377c967781471ee106e2bb4e11c8Ben Murdochvoid LayoutTestController::waitUntilDone() 118e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{ 119e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke m_waitToDump = true; 12068513a70bcd92384395513322f1b801e7bf9c729Steve Block initializeWaitToDumpWatchdogTimerIfNeeded(); 121e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke} 122e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 123e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid LayoutTestController::waitToDumpWatchdogTimerFired() 124e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{ 12568513a70bcd92384395513322f1b801e7bf9c729Steve Block invalidateWaitToDumpWatchdogTimer(); 126e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke const char* message = "FAIL: Timed out waiting for notifyDone to be called\n"; 127e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke InjectedBundle::shared().os() << message << "\n"; 128e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke InjectedBundle::shared().done(); 129e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke} 130e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 131e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkevoid LayoutTestController::notifyDone() 132e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{ 133cad810f21b803229eb11403f9209855525a25d57Steve Block if (!InjectedBundle::shared().isTestRunning()) 134cad810f21b803229eb11403f9209855525a25d57Steve Block return; 135cad810f21b803229eb11403f9209855525a25d57Steve Block 136ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (m_waitToDump && !InjectedBundle::shared().topLoadingFrame()) 137e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke InjectedBundle::shared().page()->dump(); 138ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 139e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke m_waitToDump = false; 140e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke} 141e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 142e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkeunsigned LayoutTestController::numberOfActiveAnimations() const 143e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{ 1440617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen // FIXME: Is it OK this works only for the main frame? 1450617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen // FIXME: If this is needed only for the main frame, then why is the function on WKBundleFrame instead of WKBundlePage? 146e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); 147e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke return WKBundleFrameGetNumberOfActiveAnimations(mainFrame); 148e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke} 149e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 150e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarkebool LayoutTestController::pauseAnimationAtTimeOnElementWithId(JSStringRef animationName, double time, JSStringRef elementId) 151e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke{ 1520617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen // FIXME: Is it OK this works only for the main frame? 1530617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen // FIXME: If this is needed only for the main frame, then why is the function on WKBundleFrame instead of WKBundlePage? 1540617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); 1550617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen return WKBundleFramePauseAnimationOnElementWithId(mainFrame, toWK(animationName).get(), toWK(elementId).get(), time); 1560617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen} 157e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 15828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuvoid LayoutTestController::suspendAnimations() 15928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{ 16028040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); 16128040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu WKBundleFrameSuspendAnimations(mainFrame); 16228040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu} 16328040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu 16428040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhuvoid LayoutTestController::resumeAnimations() 16528040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu{ 16628040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); 16728040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu WKBundleFrameResumeAnimations(mainFrame); 16828040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu} 16928040489d744e0c5d475a88663056c9040ed5320Teng-Hui Zhu 170e14391e94c850b8bd03680c23b38978db68687a8John ReckJSRetainPtr<JSStringRef> LayoutTestController::layerTreeAsText() const 171e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 172e14391e94c850b8bd03680c23b38978db68687a8John Reck WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); 173e14391e94c850b8bd03680c23b38978db68687a8John Reck WKRetainPtr<WKStringRef> text(AdoptWK, WKBundleFrameCopyLayerTreeAsText(mainFrame)); 174e14391e94c850b8bd03680c23b38978db68687a8John Reck return toJS(text); 175e14391e94c850b8bd03680c23b38978db68687a8John Reck} 176e14391e94c850b8bd03680c23b38978db68687a8John Reck 1775ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid LayoutTestController::addUserScript(JSStringRef source, bool runAtStart, bool allFrames) 1785ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 1795ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen WKRetainPtr<WKStringRef> sourceWK = toWK(source); 1805ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen WKRetainPtr<WKBundleScriptWorldRef> scriptWorld(AdoptWK, WKBundleScriptWorldCreateWorld()); 1815ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 182f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch WKBundleAddUserScript(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), scriptWorld.get(), sourceWK.get(), 0, 0, 0, 1835ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen (runAtStart ? kWKInjectAtDocumentStart : kWKInjectAtDocumentEnd), 1845ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen (allFrames ? kWKInjectInAllFrames : kWKInjectInTopFrameOnly)); 1855ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 1865ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 1875ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid LayoutTestController::addUserStyleSheet(JSStringRef source, bool allFrames) 1885ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 1895ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen WKRetainPtr<WKStringRef> sourceWK = toWK(source); 1905ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen WKRetainPtr<WKBundleScriptWorldRef> scriptWorld(AdoptWK, WKBundleScriptWorldCreateWorld()); 1915ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 192f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch WKBundleAddUserStyleSheet(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), scriptWorld.get(), sourceWK.get(), 0, 0, 0, 1935ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen (allFrames ? kWKInjectInAllFrames : kWKInjectInTopFrameOnly)); 1945ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 1955ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 1960617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenvoid LayoutTestController::keepWebHistory() 1970617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{ 198dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch WKBundleSetShouldTrackVisitedLinks(InjectedBundle::shared().bundle(), true); 1990617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen} 2000617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen 2010617145a89917ae7735fe1c9538688ab9a577df5Kristian MonsenJSValueRef LayoutTestController::computedStyleIncludingVisitedInfo(JSValueRef element) 2020617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{ 2030617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen // FIXME: Is it OK this works only for the main frame? 204e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); 2050617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); 2060617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen if (!JSValueIsObject(context, element)) 2070617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen return JSValueMakeUndefined(context); 2080617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen JSValueRef value = WKBundleFrameGetComputedStyleIncludingVisitedInfo(mainFrame, const_cast<JSObjectRef>(element)); 2090617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen if (!value) 2100617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen return JSValueMakeUndefined(context); 2110617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen return value; 2120617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen} 2130617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen 2140617145a89917ae7735fe1c9538688ab9a577df5Kristian MonsenJSRetainPtr<JSStringRef> LayoutTestController::counterValueForElementById(JSStringRef elementId) 2150617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{ 2160617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); 2170617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen JSObjectRef element = getElementById(mainFrame, elementId); 2180617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen if (!element) 2190617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen return 0; 2200617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen WKRetainPtr<WKStringRef> value(AdoptWK, WKBundleFrameCopyCounterValue(mainFrame, const_cast<JSObjectRef>(element))); 2210617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen return toJS(value); 2220617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen} 2230617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen 2240617145a89917ae7735fe1c9538688ab9a577df5Kristian MonsenJSRetainPtr<JSStringRef> LayoutTestController::markerTextForListItem(JSValueRef element) 2250617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{ 2260617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); 2270617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); 2280617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen if (!element || !JSValueIsObject(context, element)) 2290617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen return 0; 2300617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen WKRetainPtr<WKStringRef> text(AdoptWK, WKBundleFrameCopyMarkerText(mainFrame, const_cast<JSObjectRef>(element))); 2310617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen if (WKStringIsEmpty(text.get())) 2320617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen return 0; 2330617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen return toJS(text); 2340617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen} 2350617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen 2360617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenvoid LayoutTestController::execCommand(JSStringRef name, JSStringRef argument) 2370617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{ 2380617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen WKBundlePageExecuteEditingCommand(InjectedBundle::shared().page()->page(), toWK(name).get(), toWK(argument).get()); 2390617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen} 2400617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen 241f05b935882198ccf7d81675736e3aeb089c5113aBen Murdochbool LayoutTestController::findString(JSStringRef target, JSValueRef optionsArrayAsValue) 242f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch{ 243f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch WKFindOptions options = 0; 244f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 245f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch WKBundleFrameRef mainFrame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); 246f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch JSContextRef context = WKBundleFrameGetJavaScriptContext(mainFrame); 247f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch JSRetainPtr<JSStringRef> lengthPropertyName(Adopt, JSStringCreateWithUTF8CString("length")); 248f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch JSObjectRef optionsArray = JSValueToObject(context, optionsArrayAsValue, 0); 249f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch JSValueRef lengthValue = JSObjectGetProperty(context, optionsArray, lengthPropertyName.get(), 0); 250f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!JSValueIsNumber(context, lengthValue)) 251f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return false; 252f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 253f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch size_t length = static_cast<size_t>(JSValueToNumber(context, lengthValue, 0)); 254f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch for (size_t i = 0; i < length; ++i) { 255f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch JSValueRef value = JSObjectGetPropertyAtIndex(context, optionsArray, i, 0); 256f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (!JSValueIsString(context, value)) 257f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch continue; 258f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 259f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch JSRetainPtr<JSStringRef> optionName(Adopt, JSValueToStringCopy(context, value, 0)); 260f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 261f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch if (JSStringIsEqualToUTF8CString(optionName.get(), "CaseInsensitive")) 262f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch options |= kWKFindOptionsCaseInsensitive; 263f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch else if (JSStringIsEqualToUTF8CString(optionName.get(), "AtWordStarts")) 264f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch options |= kWKFindOptionsAtWordStarts; 265f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch else if (JSStringIsEqualToUTF8CString(optionName.get(), "TreatMedialCapitalAsWordStart")) 266f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch options |= kWKFindOptionsTreatMedialCapitalAsWordStart; 267f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch else if (JSStringIsEqualToUTF8CString(optionName.get(), "Backwards")) 268f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch options |= kWKFindOptionsBackwards; 269f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch else if (JSStringIsEqualToUTF8CString(optionName.get(), "WrapAround")) 270f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch options |= kWKFindOptionsWrapAround; 271f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch else if (JSStringIsEqualToUTF8CString(optionName.get(), "StartInSelection")) { 272f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch // FIXME: No kWKFindOptionsStartInSelection. 273f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 274f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch } 275f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 276f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch return WKBundlePageFindString(InjectedBundle::shared().page()->page(), toWK(target).get(), options); 277f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch} 278f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch 2790617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsenbool LayoutTestController::isCommandEnabled(JSStringRef name) 2800617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen{ 2810617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen return WKBundlePageIsEditingCommandEnabled(InjectedBundle::shared().page()->page(), toWK(name).get()); 282e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke} 283e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke 284db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockvoid LayoutTestController::setCanOpenWindows(bool) 285db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block{ 286db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // It's not clear if or why any tests require opening windows be forbidden. 287db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block // For now, just ignore this setting, and if we find later it's needed we can add it. 288db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block} 289db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block 2905ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsenvoid LayoutTestController::setXSSAuditorEnabled(bool enabled) 2915ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen{ 292f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch WKBundleOverrideXSSAuditorEnabledForTestRunner(InjectedBundle::shared().bundle(), InjectedBundle::shared().pageGroup(), true); 2935ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen} 2945ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen 295db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockunsigned LayoutTestController::windowCount() 296db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block{ 297db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block return InjectedBundle::shared().pageCount(); 298db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block} 299db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block 300e14391e94c850b8bd03680c23b38978db68687a8John Reckvoid LayoutTestController::clearBackForwardList() 301e14391e94c850b8bd03680c23b38978db68687a8John Reck{ 302e14391e94c850b8bd03680c23b38978db68687a8John Reck WKBundleBackForwardListClear(WKBundlePageGetBackForwardList(InjectedBundle::shared().page()->page())); 303e14391e94c850b8bd03680c23b38978db68687a8John Reck} 304e14391e94c850b8bd03680c23b38978db68687a8John Reck 305ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block// Object Creation 306ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 307ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Blockvoid LayoutTestController::makeWindowObject(JSContextRef context, JSObjectRef windowObject, JSValueRef* exception) 308ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block{ 3090617145a89917ae7735fe1c9538688ab9a577df5Kristian Monsen setProperty(context, windowObject, "layoutTestController", this, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, exception); 310ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block} 311ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block 312ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochtypedef WTF::HashMap<unsigned, WKRetainPtr<WKBundleScriptWorldRef> > WorldMap; 313ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochstatic WorldMap& worldMap() 314ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{ 315ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch static WorldMap& map = *new WorldMap; 316ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return map; 317ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch} 318ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 319ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochunsigned LayoutTestController::worldIDForWorld(WKBundleScriptWorldRef world) 320ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{ 321ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch WorldMap::const_iterator end = worldMap().end(); 322ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch for (WorldMap::const_iterator it = worldMap().begin(); it != end; ++it) { 323ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (it->second == world) 324ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return it->first; 325ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 326ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 327ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return 0; 328ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch} 329ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 330ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochvoid LayoutTestController::evaluateScriptInIsolatedWorld(JSContextRef context, unsigned worldID, JSStringRef script) 331ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch{ 332ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch // A worldID of 0 always corresponds to a new world. Any other worldID corresponds to a world 333ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch // that is created once and cached forever. 334ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch WKRetainPtr<WKBundleScriptWorldRef> world; 335ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (!worldID) 336ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch world.adopt(WKBundleScriptWorldCreateWorld()); 337ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch else { 338ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch WKRetainPtr<WKBundleScriptWorldRef>& worldSlot = worldMap().add(worldID, 0).first->second; 339ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (!worldSlot) 340ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch worldSlot.adopt(WKBundleScriptWorldCreateWorld()); 341ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch world = worldSlot; 342ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch } 343ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 344ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch WKBundleFrameRef frame = WKBundleFrameForJavaScriptContext(context); 345ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (!frame) 346ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch frame = WKBundlePageGetMainFrame(InjectedBundle::shared().page()->page()); 347ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 348ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch JSGlobalContextRef jsContext = WKBundleFrameGetJavaScriptContextForWorld(frame, world.get()); 349ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch JSEvaluateScript(jsContext, script, 0, 0, 0, 0); 350ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch} 351ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch 352ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block} // namespace WTR 353