| /* |
| * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of |
| * its contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY |
| * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
| * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "config.h" |
| #include "LayoutTestController.h" |
| |
| #include "DumpRenderTree.h" |
| #include "EditingDelegate.h" |
| #include "PolicyDelegate.h" |
| #include "WorkQueue.h" |
| #include "WorkQueueItem.h" |
| #include <WebCore/COMPtr.h> |
| #include <wtf/Platform.h> |
| #include <wtf/RetainPtr.h> |
| #include <wtf/Vector.h> |
| #include <JavaScriptCore/Assertions.h> |
| #include <JavaScriptCore/JavaScriptCore.h> |
| #include <JavaScriptCore/JSRetainPtr.h> |
| #include <JavaScriptCore/JSStringRefBSTR.h> |
| #include <WebKit/WebKit.h> |
| #include <string> |
| #include <CoreFoundation/CoreFoundation.h> |
| #include <shlwapi.h> |
| #include <shlguid.h> |
| #include <shobjidl.h> |
| |
| using std::string; |
| using std::wstring; |
| |
| static bool resolveCygwinPath(const wstring& cygwinPath, wstring& windowsPath); |
| |
| LayoutTestController::~LayoutTestController() |
| { |
| COMPtr<IWebView> webView; |
| if (FAILED(frame->webView(&webView))) |
| return; |
| |
| // reset webview-related states back to default values in preparation for next test |
| |
| COMPtr<IWebViewPrivate> viewPrivate; |
| if (SUCCEEDED(webView->QueryInterface(&viewPrivate))) |
| viewPrivate->setTabKeyCyclesThroughElements(TRUE); |
| |
| COMPtr<IWebViewEditing> viewEditing; |
| if (FAILED(webView->QueryInterface(&viewEditing))) |
| return; |
| COMPtr<IWebEditingDelegate> delegate; |
| if (FAILED(viewEditing->editingDelegate(&delegate))) |
| return; |
| COMPtr<EditingDelegate> editingDelegate(Query, viewEditing.get()); |
| if (editingDelegate) |
| editingDelegate->setAcceptsEditing(TRUE); |
| } |
| |
| void LayoutTestController::addDisallowedURL(JSStringRef url) |
| { |
| // FIXME: Implement! |
| } |
| |
| void LayoutTestController::clearBackForwardList() |
| { |
| COMPtr<IWebView> webView; |
| if (FAILED(frame->webView(&webView))) |
| return; |
| |
| COMPtr<IWebBackForwardList> backForwardList; |
| if (FAILED(webView->backForwardList(&backForwardList))) |
| return; |
| |
| COMPtr<IWebHistoryItem> item; |
| if (FAILED(backForwardList->currentItem(&item))) |
| return; |
| |
| // We clear the history by setting the back/forward list's capacity to 0 |
| // then restoring it back and adding back the current item. |
| int capacity; |
| if (FAILED(backForwardList->capacity(&capacity))) |
| return; |
| |
| backForwardList->setCapacity(0); |
| backForwardList->setCapacity(capacity); |
| backForwardList->addItem(item.get()); |
| backForwardList->goToItem(item.get()); |
| } |
| |
| JSStringRef LayoutTestController::copyDecodedHostName(JSStringRef name) |
| { |
| // FIXME: Implement! |
| return 0; |
| } |
| |
| JSStringRef LayoutTestController::copyEncodedHostName(JSStringRef name) |
| { |
| // FIXME: Implement! |
| return 0; |
| } |
| |
| void LayoutTestController::display() |
| { |
| displayWebView(); |
| } |
| |
| void LayoutTestController::keepWebHistory() |
| { |
| COMPtr<IWebHistory> history(Create, CLSID_WebHistory); |
| if (!history) |
| return; |
| |
| COMPtr<IWebHistory> sharedHistory(Create, CLSID_WebHistory); |
| if (!sharedHistory) |
| return; |
| |
| history->setOptionalSharedHistory(sharedHistory.get()); |
| } |
| |
| void LayoutTestController::notifyDone() |
| { |
| // Same as on mac. This can be shared. |
| if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count()) |
| dump(); |
| m_waitToDump = false; |
| } |
| |
| JSStringRef LayoutTestController::pathToLocalResource(JSContextRef context, JSStringRef url) |
| { |
| wstring input(JSStringGetCharactersPtr(url), JSStringGetLength(url)); |
| |
| wstring localPath; |
| if (!resolveCygwinPath(input, localPath)) { |
| printf("ERROR: Failed to resolve Cygwin path %S\n", input.c_str()); |
| return 0; |
| } |
| |
| return JSStringCreateWithCharacters(localPath.c_str(), localPath.length()); |
| } |
| |
| void LayoutTestController::queueBackNavigation(int howFarBack) |
| { |
| // Same as on mac. This can be shared. |
| WorkQueue::shared()->queue(new BackItem(howFarBack)); |
| } |
| |
| void LayoutTestController::queueForwardNavigation(int howFarForward) |
| { |
| // Same as on mac. This can be shared. |
| WorkQueue::shared()->queue(new ForwardItem(howFarForward)); |
| } |
| |
| static wstring jsStringRefToWString(JSStringRef jsStr) |
| { |
| size_t length = JSStringGetLength(jsStr); |
| Vector<WCHAR> buffer(length + 1); |
| memcpy(buffer.data(), JSStringGetCharactersPtr(jsStr), length * sizeof(WCHAR)); |
| buffer[length] = '\0'; |
| |
| return buffer.data(); |
| } |
| |
| void LayoutTestController::queueLoad(JSStringRef url, JSStringRef target) |
| { |
| COMPtr<IWebDataSource> dataSource; |
| if (FAILED(frame->dataSource(&dataSource))) |
| return; |
| |
| COMPtr<IWebURLResponse> response; |
| if (FAILED(dataSource->response(&response)) || !response) |
| return; |
| |
| BSTR responseURLBSTR; |
| if (FAILED(response->URL(&responseURLBSTR))) |
| return; |
| wstring responseURL(responseURLBSTR, SysStringLen(responseURLBSTR)); |
| SysFreeString(responseURLBSTR); |
| |
| // FIXME: We should do real relative URL resolution here. |
| int lastSlash = responseURL.rfind('/'); |
| if (lastSlash != -1) |
| responseURL = responseURL.substr(0, lastSlash); |
| |
| wstring wURL = jsStringRefToWString(url); |
| wstring wAbsoluteURL = responseURL + TEXT("/") + wURL; |
| JSRetainPtr<JSStringRef> jsAbsoluteURL(Adopt, JSStringCreateWithCharacters(wAbsoluteURL.data(), wAbsoluteURL.length())); |
| |
| WorkQueue::shared()->queue(new LoadItem(jsAbsoluteURL.get(), target)); |
| } |
| |
| void LayoutTestController::queueReload() |
| { |
| WorkQueue::shared()->queue(new ReloadItem); |
| } |
| |
| void LayoutTestController::queueScript(JSStringRef script) |
| { |
| WorkQueue::shared()->queue(new ScriptItem(script)); |
| } |
| |
| void LayoutTestController::setAcceptsEditing(bool acceptsEditing) |
| { |
| COMPtr<IWebView> webView; |
| if (FAILED(frame->webView(&webView))) |
| return; |
| |
| COMPtr<IWebViewEditing> viewEditing; |
| if (FAILED(webView->QueryInterface(&viewEditing))) |
| return; |
| |
| COMPtr<IWebEditingDelegate> delegate; |
| if (FAILED(viewEditing->editingDelegate(&delegate))) |
| return; |
| |
| EditingDelegate* editingDelegate = (EditingDelegate*)(IWebEditingDelegate*)delegate.get(); |
| editingDelegate->setAcceptsEditing(acceptsEditing); |
| } |
| |
| void LayoutTestController::setAuthorAndUserStylesEnabled(bool flag) |
| { |
| COMPtr<IWebView> webView; |
| if (FAILED(frame->webView(&webView))) |
| return; |
| |
| COMPtr<IWebPreferences> preferences; |
| if (FAILED(webView->preferences(&preferences))) |
| return; |
| |
| COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences); |
| if (!prefsPrivate) |
| return; |
| |
| prefsPrivate->setAuthorAndUserStylesEnabled(flag); |
| } |
| |
| void LayoutTestController::setCustomPolicyDelegate(bool setDelegate, bool permissive) |
| { |
| COMPtr<IWebView> webView; |
| if (FAILED(frame->webView(&webView))) |
| return; |
| |
| if (setDelegate) { |
| policyDelegate->setPermissive(permissive); |
| webView->setPolicyDelegate(policyDelegate); |
| } else |
| webView->setPolicyDelegate(NULL); |
| } |
| |
| void LayoutTestController::setMainFrameIsFirstResponder(bool flag) |
| { |
| // FIXME: Implement! |
| } |
| |
| void LayoutTestController::setPrivateBrowsingEnabled(bool privateBrowsingEnabled) |
| { |
| COMPtr<IWebView> webView; |
| if (FAILED(frame->webView(&webView))) |
| return; |
| |
| COMPtr<IWebPreferences> preferences; |
| if (FAILED(webView->preferences(&preferences))) |
| return; |
| |
| preferences->setPrivateBrowsingEnabled(privateBrowsingEnabled); |
| } |
| |
| void LayoutTestController::setPopupBlockingEnabled(bool privateBrowsingEnabled) |
| { |
| COMPtr<IWebView> webView; |
| if (FAILED(frame->webView(&webView))) |
| return; |
| |
| COMPtr<IWebPreferences> preferences; |
| if (FAILED(webView->preferences(&preferences))) |
| return; |
| |
| preferences->setJavaScriptCanOpenWindowsAutomatically(!privateBrowsingEnabled); |
| } |
| |
| void LayoutTestController::setTabKeyCyclesThroughElements(bool shouldCycle) |
| { |
| COMPtr<IWebView> webView; |
| if (FAILED(frame->webView(&webView))) |
| return; |
| |
| COMPtr<IWebViewPrivate> viewPrivate; |
| if (FAILED(webView->QueryInterface(&viewPrivate))) |
| return; |
| |
| viewPrivate->setTabKeyCyclesThroughElements(shouldCycle ? TRUE : FALSE); |
| } |
| |
| void LayoutTestController::setUseDashboardCompatibilityMode(bool flag) |
| { |
| // FIXME: Implement! |
| } |
| |
| void LayoutTestController::setUserStyleSheetEnabled(bool flag) |
| { |
| COMPtr<IWebView> webView; |
| if (FAILED(frame->webView(&webView))) |
| return; |
| |
| COMPtr<IWebPreferences> preferences; |
| if (FAILED(webView->preferences(&preferences))) |
| return; |
| |
| preferences->setUserStyleSheetEnabled(flag); |
| } |
| |
| bool appendComponentToPath(wstring& path, const wstring& component) |
| { |
| WCHAR buffer[MAX_PATH]; |
| |
| if (path.size() + 1 > MAX_PATH) |
| return false; |
| |
| memcpy(buffer, path.data(), path.size() * sizeof(WCHAR)); |
| buffer[path.size()] = '\0'; |
| |
| if (!PathAppendW(buffer, component.c_str())) |
| return false; |
| |
| path = wstring(buffer); |
| return true; |
| } |
| |
| static bool followShortcuts(wstring& path) |
| { |
| if (PathFileExists(path.c_str())) |
| return true; |
| |
| // Do we have a shortcut? |
| wstring linkPath = path; |
| linkPath.append(TEXT(".lnk")); |
| if (!PathFileExists(linkPath.c_str())) |
| return true; |
| |
| // We have a shortcut, find its target. |
| COMPtr<IShellLink> shortcut(Create, CLSID_ShellLink); |
| if (!shortcut) |
| return false; |
| COMPtr<IPersistFile> persistFile(Query, shortcut); |
| if (!shortcut) |
| return false; |
| if (FAILED(persistFile->Load(linkPath.c_str(), STGM_READ))) |
| return false; |
| if (FAILED(shortcut->Resolve(0, 0))) |
| return false; |
| WCHAR targetPath[MAX_PATH]; |
| DWORD targetPathLen = _countof(targetPath); |
| if (FAILED(shortcut->GetPath(targetPath, targetPathLen, 0, 0))) |
| return false; |
| if (!PathFileExists(targetPath)) |
| return false; |
| // Use the target path as the result path instead. |
| path = wstring(targetPath); |
| |
| return true; |
| } |
| |
| static bool resolveCygwinPath(const wstring& cygwinPath, wstring& windowsPath) |
| { |
| wstring fileProtocol = L"file://"; |
| bool isFileProtocol = cygwinPath.find(fileProtocol) != string::npos; |
| if (cygwinPath[isFileProtocol ? 7 : 0] != '/') // ensure path is absolute |
| return false; |
| |
| // Get the Root path. |
| WCHAR rootPath[MAX_PATH]; |
| DWORD rootPathSize = _countof(rootPath); |
| DWORD keyType; |
| DWORD result = ::SHGetValueW(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Cygnus Solutions\\Cygwin\\mounts v2\\/"), TEXT("native"), &keyType, &rootPath, &rootPathSize); |
| |
| if (result != ERROR_SUCCESS || keyType != REG_SZ) |
| return false; |
| |
| windowsPath = wstring(rootPath, rootPathSize); |
| |
| int oldPos = isFileProtocol ? 8 : 1; |
| while (1) { |
| int newPos = cygwinPath.find('/', oldPos); |
| |
| if (newPos == -1) { |
| wstring pathComponent = cygwinPath.substr(oldPos); |
| |
| if (!appendComponentToPath(windowsPath, pathComponent)) |
| return false; |
| |
| if (!followShortcuts(windowsPath)) |
| return false; |
| |
| break; |
| } |
| |
| wstring pathComponent = cygwinPath.substr(oldPos, newPos - oldPos); |
| if (!appendComponentToPath(windowsPath, pathComponent)) |
| return false; |
| |
| if (!followShortcuts(windowsPath)) |
| return false; |
| |
| oldPos = newPos + 1; |
| } |
| |
| if (isFileProtocol) |
| windowsPath = fileProtocol + windowsPath; |
| |
| return true; |
| } |
| |
| static wstring cfStringRefToWString(CFStringRef cfStr) |
| { |
| Vector<wchar_t> v(CFStringGetLength(cfStr)); |
| CFStringGetCharacters(cfStr, CFRangeMake(0, CFStringGetLength(cfStr)), (UniChar *)v.data()); |
| |
| return wstring(v.data(), v.size()); |
| } |
| |
| void LayoutTestController::setUserStyleSheetLocation(JSStringRef jsURL) |
| { |
| COMPtr<IWebView> webView; |
| if (FAILED(frame->webView(&webView))) |
| return; |
| |
| COMPtr<IWebPreferences> preferences; |
| if (FAILED(webView->preferences(&preferences))) |
| return; |
| |
| RetainPtr<CFStringRef> urlString(AdoptCF, JSStringCopyCFString(0, jsURL)); |
| RetainPtr<CFURLRef> url(AdoptCF, CFURLCreateWithString(0, urlString.get(), 0)); |
| if (!url) |
| return; |
| |
| // Now copy the file system path, POSIX style. |
| RetainPtr<CFStringRef> pathCF(AdoptCF, CFURLCopyFileSystemPath(url.get(), kCFURLPOSIXPathStyle)); |
| if (!pathCF) |
| return; |
| |
| wstring path = cfStringRefToWString(pathCF.get()); |
| |
| wstring resultPath; |
| if (!resolveCygwinPath(path, resultPath)) |
| return; |
| |
| // The path has been resolved, now convert it back to a CFURL. |
| int result = WideCharToMultiByte(CP_UTF8, 0, resultPath.c_str(), resultPath.size() + 1, 0, 0, 0, 0); |
| Vector<char> utf8Vector(result); |
| result = WideCharToMultiByte(CP_UTF8, 0, resultPath.c_str(), resultPath.size() + 1, utf8Vector.data(), result, 0, 0); |
| if (!result) |
| return; |
| |
| url = CFURLCreateFromFileSystemRepresentation(0, (const UInt8*)utf8Vector.data(), utf8Vector.size() - 1, false); |
| if (!url) |
| return; |
| |
| resultPath = cfStringRefToWString(CFURLGetString(url.get())); |
| |
| BSTR resultPathBSTR = SysAllocStringLen(resultPath.data(), resultPath.size()); |
| preferences->setUserStyleSheetLocation(resultPathBSTR); |
| SysFreeString(resultPathBSTR); |
| } |
| |
| void LayoutTestController::setPersistentUserStyleSheetLocation(JSStringRef jsURL) |
| { |
| RetainPtr<CFStringRef> urlString(AdoptCF, JSStringCopyCFString(0, jsURL)); |
| ::setPersistentUserStyleSheetLocation(urlString.get()); |
| } |
| |
| void LayoutTestController::clearPersistentUserStyleSheet() |
| { |
| ::setPersistentUserStyleSheetLocation(0); |
| } |
| |
| void LayoutTestController::setWindowIsKey(bool flag) |
| { |
| COMPtr<IWebView> webView; |
| if (FAILED(frame->webView(&webView))) |
| return; |
| |
| COMPtr<IWebViewPrivate> viewPrivate; |
| if (FAILED(webView->QueryInterface(&viewPrivate))) |
| return; |
| |
| HWND webViewWindow; |
| if (FAILED(viewPrivate->viewWindow((OLE_HANDLE*)&webViewWindow))) |
| return; |
| |
| ::SendMessage(webViewWindow, flag ? WM_SETFOCUS : WM_KILLFOCUS, (WPARAM)::GetDesktopWindow(), 0); |
| } |
| |
| void LayoutTestController::setSmartInsertDeleteEnabled(bool flag) |
| { |
| COMPtr<IWebView> webView; |
| if (FAILED(frame->webView(&webView))) |
| return; |
| |
| COMPtr<IWebViewEditing> viewEditing; |
| if (FAILED(webView->QueryInterface(&viewEditing))) |
| return; |
| |
| viewEditing->setSmartInsertDeleteEnabled(flag ? TRUE : FALSE); |
| } |
| |
| void LayoutTestController::setJavaScriptProfilingEnabled(bool flag) |
| { |
| COMPtr<IWebView> webView; |
| if (FAILED(frame->webView(&webView))) |
| return; |
| |
| COMPtr<IWebViewPrivate> viewPrivate; |
| if (FAILED(webView->QueryInterface(&viewPrivate))) |
| return; |
| |
| COMPtr<IWebPreferences> preferences; |
| if (FAILED(webView->preferences(&preferences))) |
| return; |
| |
| COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences); |
| if (!prefsPrivate) |
| return; |
| |
| COMPtr<IWebInspector> inspector; |
| if (FAILED(viewPrivate->inspector(&inspector))) |
| return; |
| |
| prefsPrivate->setDeveloperExtrasEnabled(flag); |
| inspector->setJavaScriptProfilingEnabled(flag); |
| } |
| |
| void LayoutTestController::setSelectTrailingWhitespaceEnabled(bool flag) |
| { |
| COMPtr<IWebView> webView; |
| if (FAILED(frame->webView(&webView))) |
| return; |
| |
| COMPtr<IWebViewEditing> viewEditing; |
| if (FAILED(webView->QueryInterface(&viewEditing))) |
| return; |
| |
| viewEditing->setSelectTrailingWhitespaceEnabled(flag ? TRUE : FALSE); |
| } |
| |
| static const CFTimeInterval waitToDumpWatchdogInterval = 10.0; |
| |
| static void waitUntilDoneWatchdogFired(CFRunLoopTimerRef timer, void* info) |
| { |
| const char* message = "FAIL: Timed out waiting for notifyDone to be called\n"; |
| fprintf(stderr, message); |
| fprintf(stdout, message); |
| dump(); |
| } |
| |
| void LayoutTestController::setWaitToDump(bool waitUntilDone) |
| { |
| // Same as on mac. This can be shared. |
| m_waitToDump = waitUntilDone; |
| if (m_waitToDump && !waitToDumpWatchdog) { |
| waitToDumpWatchdog = CFRunLoopTimerCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent() + waitToDumpWatchdogInterval, 0, 0, 0, waitUntilDoneWatchdogFired, NULL); |
| CFRunLoopAddTimer(CFRunLoopGetCurrent(), waitToDumpWatchdog, kCFRunLoopCommonModes); |
| } |
| } |
| |
| int LayoutTestController::windowCount() |
| { |
| return openWindows().size(); |
| } |
| |
| bool LayoutTestController::elementDoesAutoCompleteForElementWithId(JSStringRef id) |
| { |
| COMPtr<IDOMDocument> document; |
| if (FAILED(frame->DOMDocument(&document))) |
| return false; |
| |
| wstring idWstring = jsStringRefToWString(id); |
| BSTR idBSTR = SysAllocStringLen((OLECHAR*)idWstring.c_str(), idWstring.length()); |
| COMPtr<IDOMElement> element; |
| HRESULT result = document->getElementById(idBSTR, &element); |
| SysFreeString(idBSTR); |
| |
| if (FAILED(result)) |
| return false; |
| |
| COMPtr<IWebFramePrivate> framePrivate(Query, frame); |
| if (!framePrivate) |
| return false; |
| |
| BOOL autoCompletes; |
| if (FAILED(framePrivate->elementDoesAutoComplete(element.get(), &autoCompletes))) |
| return false; |
| |
| return autoCompletes; |
| } |
| |
| void LayoutTestController::execCommand(JSStringRef name, JSStringRef value) |
| { |
| wstring wName = jsStringRefToWString(name); |
| wstring wValue = jsStringRefToWString(value); |
| |
| COMPtr<IWebView> webView; |
| if (FAILED(frame->webView(&webView))) |
| return; |
| |
| COMPtr<IWebViewPrivate> viewPrivate; |
| if (FAILED(webView->QueryInterface(&viewPrivate))) |
| return; |
| |
| BSTR nameBSTR = SysAllocStringLen((OLECHAR*)wName.c_str(), wName.length()); |
| BSTR valueBSTR = SysAllocStringLen((OLECHAR*)wValue.c_str(), wValue.length()); |
| viewPrivate->executeCoreCommandByName(nameBSTR, valueBSTR); |
| |
| SysFreeString(nameBSTR); |
| SysFreeString(valueBSTR); |
| } |
| |
| bool LayoutTestController::isCommandEnabled(JSStringRef /*name*/) |
| { |
| printf("ERROR: LayoutTestController::isCommandEnabled() not implemented\n"); |
| return false; |
| } |
| |
| void LayoutTestController::clearAllDatabases() |
| { |
| printf("ERROR: LayoutTestController::clearAllDatabases() not implemented\n"); |
| } |
| |
| void LayoutTestController::setDatabaseQuota(unsigned long long quota) |
| { |
| printf("ERROR: LayoutTestController::setDatabaseQuota() not implemented\n"); |
| } |
| |
| bool LayoutTestController::pauseAnimationAtTimeOnElementWithId(JSStringRef animationName, double time, JSStringRef elementId) |
| { |
| return false; // FIXME: Implement this on Windows |
| } |
| |
| bool LayoutTestController::pauseTransitionAtTimeOnElementWithId(JSStringRef propertyName, double time, JSStringRef elementId) |
| { |
| return false; // FIXME: Implement this on Windows |
| } |
| |
| void LayoutTestController::overridePreference(JSStringRef key, JSStringRef flag) |
| { |
| COMPtr<IWebView> webView; |
| if (FAILED(frame->webView(&webView))) |
| return; |
| |
| COMPtr<IWebPreferences> preferences; |
| if (FAILED(webView->preferences(&preferences))) |
| return; |
| |
| COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences); |
| if (!prefsPrivate) |
| return; |
| |
| BSTR keyBSTR = JSStringCopyBSTR(key); |
| BSTR flagBSTR = JSStringCopyBSTR(flag); |
| prefsPrivate->overridePreference(keyBSTR, flagBSTR); |
| SysFreeString(keyBSTR); |
| SysFreeString(flagBSTR); |
| } |