• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1.  Redistributions of source code must retain the above copyright
9  *     notice, this list of conditions and the following disclaimer.
10  * 2.  Redistributions in binary form must reproduce the above copyright
11  *     notice, this list of conditions and the following disclaimer in the
12  *     documentation and/or other materials provided with the distribution.
13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14  *     its contributors may be used to endorse or promote products derived
15  *     from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include "config.h"
30 #include "LayoutTestController.h"
31 
32 #include "DumpRenderTree.h"
33 #include "EditingDelegate.h"
34 #include "PolicyDelegate.h"
35 #include "WorkQueue.h"
36 #include "WorkQueueItem.h"
37 #include <CoreFoundation/CoreFoundation.h>
38 #include <JavaScriptCore/Assertions.h>
39 #include <JavaScriptCore/JSRetainPtr.h>
40 #include <JavaScriptCore/JSStringRefBSTR.h>
41 #include <JavaScriptCore/JavaScriptCore.h>
42 #include <WebCore/COMPtr.h>
43 #include <WebKit/WebKit.h>
44 #include <WebKit/WebKitCOMAPI.h>
45 #include <comutil.h>
46 #include <shlwapi.h>
47 #include <shlguid.h>
48 #include <shobjidl.h>
49 #include <string>
50 #include <wtf/Platform.h>
51 #include <wtf/RetainPtr.h>
52 #include <wtf/Vector.h>
53 
54 using std::string;
55 using std::wstring;
56 
57 static bool resolveCygwinPath(const wstring& cygwinPath, wstring& windowsPath);
58 
~LayoutTestController()59 LayoutTestController::~LayoutTestController()
60 {
61     COMPtr<IWebView> webView;
62     if (FAILED(frame->webView(&webView)))
63         return;
64 
65     // reset webview-related states back to default values in preparation for next test
66 
67     COMPtr<IWebViewPrivate> viewPrivate;
68     if (SUCCEEDED(webView->QueryInterface(&viewPrivate)))
69         viewPrivate->setTabKeyCyclesThroughElements(TRUE);
70 
71     COMPtr<IWebViewEditing> viewEditing;
72     if (FAILED(webView->QueryInterface(&viewEditing)))
73         return;
74     COMPtr<IWebEditingDelegate> delegate;
75     if (FAILED(viewEditing->editingDelegate(&delegate)))
76         return;
77     COMPtr<EditingDelegate> editingDelegate(Query, viewEditing.get());
78     if (editingDelegate)
79         editingDelegate->setAcceptsEditing(TRUE);
80 }
81 
addDisallowedURL(JSStringRef url)82 void LayoutTestController::addDisallowedURL(JSStringRef url)
83 {
84     // FIXME: Implement!
85 }
86 
clearBackForwardList()87 void LayoutTestController::clearBackForwardList()
88 {
89     COMPtr<IWebView> webView;
90     if (FAILED(frame->webView(&webView)))
91         return;
92 
93     COMPtr<IWebBackForwardList> backForwardList;
94     if (FAILED(webView->backForwardList(&backForwardList)))
95         return;
96 
97     COMPtr<IWebHistoryItem> item;
98     if (FAILED(backForwardList->currentItem(&item)))
99         return;
100 
101     // We clear the history by setting the back/forward list's capacity to 0
102     // then restoring it back and adding back the current item.
103     int capacity;
104     if (FAILED(backForwardList->capacity(&capacity)))
105         return;
106 
107     backForwardList->setCapacity(0);
108     backForwardList->setCapacity(capacity);
109     backForwardList->addItem(item.get());
110     backForwardList->goToItem(item.get());
111 }
112 
callShouldCloseOnWebView()113 bool LayoutTestController::callShouldCloseOnWebView()
114 {
115     COMPtr<IWebView> webView;
116     if (FAILED(frame->webView(&webView)))
117         return false;
118 
119     COMPtr<IWebViewPrivate> viewPrivate;
120     if (FAILED(webView->QueryInterface(&viewPrivate)))
121         return false;
122 
123     BOOL result;
124     viewPrivate->shouldClose(&result);
125     return result;
126 }
127 
copyDecodedHostName(JSStringRef name)128 JSStringRef LayoutTestController::copyDecodedHostName(JSStringRef name)
129 {
130     // FIXME: Implement!
131     return 0;
132 }
133 
copyEncodedHostName(JSStringRef name)134 JSStringRef LayoutTestController::copyEncodedHostName(JSStringRef name)
135 {
136     // FIXME: Implement!
137     return 0;
138 }
139 
disableImageLoading()140 void LayoutTestController::disableImageLoading()
141 {
142     COMPtr<IWebView> webView;
143     if (FAILED(frame->webView(&webView)))
144         return;
145 
146     COMPtr<IWebPreferences> preferences;
147     if (FAILED(webView->preferences(&preferences)))
148         return;
149 
150     preferences->setLoadsImagesAutomatically(FALSE);
151 }
152 
dispatchPendingLoadRequests()153 void LayoutTestController::dispatchPendingLoadRequests()
154 {
155     // FIXME: Implement for testing fix for 6727495
156 }
157 
display()158 void LayoutTestController::display()
159 {
160     displayWebView();
161 }
162 
keepWebHistory()163 void LayoutTestController::keepWebHistory()
164 {
165     COMPtr<IWebHistory> history;
166     if (FAILED(WebKitCreateInstance(CLSID_WebHistory, 0, __uuidof(history), reinterpret_cast<void**>(&history))))
167         return;
168 
169     COMPtr<IWebHistory> sharedHistory;
170     if (FAILED(WebKitCreateInstance(CLSID_WebHistory, 0, __uuidof(sharedHistory), reinterpret_cast<void**>(&sharedHistory))))
171         return;
172 
173     history->setOptionalSharedHistory(sharedHistory.get());
174 }
175 
computedStyleIncludingVisitedInfo(JSContextRef context,JSValueRef value)176 JSValueRef LayoutTestController::computedStyleIncludingVisitedInfo(JSContextRef context, JSValueRef value)
177 {
178     // FIXME: Implement this.
179     return JSValueMakeUndefined(context);
180 }
181 
nodesFromRect(JSContextRef context,JSValueRef value,int x,int y,unsigned top,unsigned right,unsigned bottom,unsigned left,bool ignoreClipping)182 JSValueRef LayoutTestController::nodesFromRect(JSContextRef context, JSValueRef value, int x, int y, unsigned top, unsigned right, unsigned bottom, unsigned left, bool ignoreClipping)
183 {
184     // FIXME: Implement this.
185     return JSValueMakeUndefined(context);
186 }
187 
layerTreeAsText() const188 JSRetainPtr<JSStringRef> LayoutTestController::layerTreeAsText() const
189 {
190     COMPtr<IWebFramePrivate> framePrivate(Query, frame);
191     if (!framePrivate)
192         return false;
193 
194     BSTR textBSTR = 0;
195     HRESULT hr = framePrivate->layerTreeAsText(&textBSTR);
196 
197     wstring text(textBSTR, SysStringLen(textBSTR));
198     SysFreeString(textBSTR);
199     JSRetainPtr<JSStringRef> textValueJS(Adopt, JSStringCreateWithCharacters(text.data(), text.length()));
200     return textValueJS;
201 }
202 
markerTextForListItem(JSContextRef context,JSValueRef nodeObject) const203 JSRetainPtr<JSStringRef> LayoutTestController::markerTextForListItem(JSContextRef context, JSValueRef nodeObject) const
204 {
205     COMPtr<IWebView> webView;
206     if (FAILED(frame->webView(&webView)))
207         return 0;
208 
209     COMPtr<IWebViewPrivate> webViewPrivate(Query, webView);
210     if (!webViewPrivate)
211         return 0;
212 
213     COMPtr<IDOMElement> element;
214     if (FAILED(webViewPrivate->elementFromJS(context, nodeObject, &element)))
215         return 0;
216 
217     COMPtr<IDOMElementPrivate> elementPrivate(Query, element);
218     if (!elementPrivate)
219         return 0;
220 
221     BSTR textBSTR = 0;
222     if (FAILED(elementPrivate->markerTextForListItem(&textBSTR)))
223         return 0;
224 
225     JSRetainPtr<JSStringRef> markerText(Adopt, JSStringCreateWithBSTR(textBSTR));
226     SysFreeString(textBSTR);
227     return markerText;
228 }
229 
waitForPolicyDelegate()230 void LayoutTestController::waitForPolicyDelegate()
231 {
232     COMPtr<IWebView> webView;
233     if (FAILED(frame->webView(&webView)))
234         return;
235 
236     setWaitToDump(true);
237     policyDelegate->setControllerToNotifyDone(this);
238     webView->setPolicyDelegate(policyDelegate);
239 }
240 
webHistoryItemCount()241 size_t LayoutTestController::webHistoryItemCount()
242 {
243     COMPtr<IWebHistory> history;
244     if (FAILED(WebKitCreateInstance(CLSID_WebHistory, 0, __uuidof(history), reinterpret_cast<void**>(&history))))
245         return 0;
246 
247     COMPtr<IWebHistory> sharedHistory;
248     if (FAILED(history->optionalSharedHistory(&sharedHistory)) || !sharedHistory)
249         return 0;
250 
251     COMPtr<IWebHistoryPrivate> sharedHistoryPrivate;
252     if (FAILED(sharedHistory->QueryInterface(&sharedHistoryPrivate)))
253         return 0;
254 
255     int count;
256     if (FAILED(sharedHistoryPrivate->allItems(&count, 0)))
257         return 0;
258 
259     return count;
260 }
261 
workerThreadCount() const262 unsigned LayoutTestController::workerThreadCount() const
263 {
264     COMPtr<IWebWorkersPrivate> workers;
265     if (FAILED(WebKitCreateInstance(CLSID_WebWorkersPrivate, 0, __uuidof(workers), reinterpret_cast<void**>(&workers))))
266         return 0;
267     unsigned count;
268     if (FAILED(workers->workerThreadCount(&count)))
269         return 0;
270     return count;
271 }
272 
notifyDone()273 void LayoutTestController::notifyDone()
274 {
275     // Same as on mac.  This can be shared.
276     if (m_waitToDump && !topLoadingFrame && !WorkQueue::shared()->count())
277         dump();
278     m_waitToDump = false;
279 }
280 
pathToLocalResource(JSContextRef context,JSStringRef url)281 JSStringRef LayoutTestController::pathToLocalResource(JSContextRef context, JSStringRef url)
282 {
283     wstring input(JSStringGetCharactersPtr(url), JSStringGetLength(url));
284 
285     wstring localPath;
286     if (!resolveCygwinPath(input, localPath)) {
287         printf("ERROR: Failed to resolve Cygwin path %S\n", input.c_str());
288         return 0;
289     }
290 
291     return JSStringCreateWithCharacters(localPath.c_str(), localPath.length());
292 }
293 
jsStringRefToWString(JSStringRef jsStr)294 static wstring jsStringRefToWString(JSStringRef jsStr)
295 {
296     size_t length = JSStringGetLength(jsStr);
297     Vector<WCHAR> buffer(length + 1);
298     memcpy(buffer.data(), JSStringGetCharactersPtr(jsStr), length * sizeof(WCHAR));
299     buffer[length] = '\0';
300 
301     return buffer.data();
302 }
303 
queueLoad(JSStringRef url,JSStringRef target)304 void LayoutTestController::queueLoad(JSStringRef url, JSStringRef target)
305 {
306     COMPtr<IWebDataSource> dataSource;
307     if (FAILED(frame->dataSource(&dataSource)))
308         return;
309 
310     COMPtr<IWebURLResponse> response;
311     if (FAILED(dataSource->response(&response)) || !response)
312         return;
313 
314     BSTR responseURLBSTR;
315     if (FAILED(response->URL(&responseURLBSTR)))
316         return;
317     wstring responseURL(responseURLBSTR, SysStringLen(responseURLBSTR));
318     SysFreeString(responseURLBSTR);
319 
320     // FIXME: We should do real relative URL resolution here.
321     int lastSlash = responseURL.rfind('/');
322     if (lastSlash != -1)
323         responseURL = responseURL.substr(0, lastSlash);
324 
325     wstring wURL = jsStringRefToWString(url);
326     wstring wAbsoluteURL = responseURL + TEXT("/") + wURL;
327     JSRetainPtr<JSStringRef> jsAbsoluteURL(Adopt, JSStringCreateWithCharacters(wAbsoluteURL.data(), wAbsoluteURL.length()));
328 
329     WorkQueue::shared()->queue(new LoadItem(jsAbsoluteURL.get(), target));
330 }
331 
setAcceptsEditing(bool acceptsEditing)332 void LayoutTestController::setAcceptsEditing(bool acceptsEditing)
333 {
334     COMPtr<IWebView> webView;
335     if (FAILED(frame->webView(&webView)))
336         return;
337 
338     COMPtr<IWebViewEditing> viewEditing;
339     if (FAILED(webView->QueryInterface(&viewEditing)))
340         return;
341 
342     COMPtr<IWebEditingDelegate> delegate;
343     if (FAILED(viewEditing->editingDelegate(&delegate)))
344         return;
345 
346     EditingDelegate* editingDelegate = (EditingDelegate*)(IWebEditingDelegate*)delegate.get();
347     editingDelegate->setAcceptsEditing(acceptsEditing);
348 }
349 
setAlwaysAcceptCookies(bool alwaysAcceptCookies)350 void LayoutTestController::setAlwaysAcceptCookies(bool alwaysAcceptCookies)
351 {
352     if (alwaysAcceptCookies == m_alwaysAcceptCookies)
353         return;
354 
355     if (!::setAlwaysAcceptCookies(alwaysAcceptCookies))
356         return;
357     m_alwaysAcceptCookies = alwaysAcceptCookies;
358 }
359 
setAuthorAndUserStylesEnabled(bool flag)360 void LayoutTestController::setAuthorAndUserStylesEnabled(bool flag)
361 {
362     COMPtr<IWebView> webView;
363     if (FAILED(frame->webView(&webView)))
364         return;
365 
366     COMPtr<IWebPreferences> preferences;
367     if (FAILED(webView->preferences(&preferences)))
368         return;
369 
370     COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
371     if (!prefsPrivate)
372         return;
373 
374     prefsPrivate->setAuthorAndUserStylesEnabled(flag);
375 }
376 
setAutofilled(JSContextRef context,JSValueRef nodeObject,bool autofilled)377 void LayoutTestController::setAutofilled(JSContextRef context, JSValueRef nodeObject, bool autofilled)
378 {
379     COMPtr<IWebView> webView;
380     if (FAILED(frame->webView(&webView)))
381         return;
382 
383     COMPtr<IWebViewPrivate> webViewPrivate(Query, webView);
384     if (!webViewPrivate)
385         return;
386 
387     COMPtr<IDOMElement> element;
388     if (FAILED(webViewPrivate->elementFromJS(context, nodeObject, &element)))
389         return;
390 
391     COMPtr<IFormsAutoFillTransition> autofillElement(Query, element);
392     if (!autofillElement)
393         return;
394 
395     autofillElement->setAutofilled(autofilled);
396 }
397 
setCustomPolicyDelegate(bool setDelegate,bool permissive)398 void LayoutTestController::setCustomPolicyDelegate(bool setDelegate, bool permissive)
399 {
400     COMPtr<IWebView> webView;
401     if (FAILED(frame->webView(&webView)))
402         return;
403 
404     if (setDelegate) {
405         policyDelegate->setPermissive(permissive);
406         webView->setPolicyDelegate(policyDelegate);
407     } else
408         webView->setPolicyDelegate(0);
409 }
410 
setMockDeviceOrientation(bool canProvideAlpha,double alpha,bool canProvideBeta,double beta,bool canProvideGamma,double gamma)411 void LayoutTestController::setMockDeviceOrientation(bool canProvideAlpha, double alpha, bool canProvideBeta, double beta, bool canProvideGamma, double gamma)
412 {
413     // FIXME: Implement for DeviceOrientation layout tests.
414     // See https://bugs.webkit.org/show_bug.cgi?id=30335.
415 }
416 
setMockGeolocationPosition(double latitude,double longitude,double accuracy)417 void LayoutTestController::setMockGeolocationPosition(double latitude, double longitude, double accuracy)
418 {
419     // FIXME: Implement for Geolocation layout tests.
420     // See https://bugs.webkit.org/show_bug.cgi?id=28264.
421 }
422 
setMockGeolocationError(int code,JSStringRef message)423 void LayoutTestController::setMockGeolocationError(int code, JSStringRef message)
424 {
425     // FIXME: Implement for Geolocation layout tests.
426     // See https://bugs.webkit.org/show_bug.cgi?id=28264.
427 }
428 
setGeolocationPermission(bool allow)429 void LayoutTestController::setGeolocationPermission(bool allow)
430 {
431     // FIXME: Implement for Geolocation layout tests.
432     setGeolocationPermissionCommon(allow);
433 }
434 
numberOfPendingGeolocationPermissionRequests()435 int LayoutTestController::numberOfPendingGeolocationPermissionRequests()
436 {
437     // FIXME: Implement for Geolocation layout tests.
438     return -1;
439 }
440 
addMockSpeechInputResult(JSStringRef result,double confidence,JSStringRef language)441 void LayoutTestController::addMockSpeechInputResult(JSStringRef result, double confidence, JSStringRef language)
442 {
443     // FIXME: Implement for speech input layout tests.
444     // See https://bugs.webkit.org/show_bug.cgi?id=39485.
445 }
446 
setIconDatabaseEnabled(bool iconDatabaseEnabled)447 void LayoutTestController::setIconDatabaseEnabled(bool iconDatabaseEnabled)
448 {
449     // See also <rdar://problem/6480108>
450     COMPtr<IWebIconDatabase> iconDatabase;
451     COMPtr<IWebIconDatabase> tmpIconDatabase;
452     if (FAILED(WebKitCreateInstance(CLSID_WebIconDatabase, 0, IID_IWebIconDatabase, (void**)&tmpIconDatabase)))
453         return;
454     if (FAILED(tmpIconDatabase->sharedIconDatabase(&iconDatabase)))
455         return;
456 
457     iconDatabase->setEnabled(iconDatabaseEnabled);
458 }
459 
setMainFrameIsFirstResponder(bool flag)460 void LayoutTestController::setMainFrameIsFirstResponder(bool flag)
461 {
462     // FIXME: Implement!
463 }
464 
setPrivateBrowsingEnabled(bool privateBrowsingEnabled)465 void LayoutTestController::setPrivateBrowsingEnabled(bool privateBrowsingEnabled)
466 {
467     COMPtr<IWebView> webView;
468     if (FAILED(frame->webView(&webView)))
469         return;
470 
471     COMPtr<IWebPreferences> preferences;
472     if (FAILED(webView->preferences(&preferences)))
473         return;
474 
475     preferences->setPrivateBrowsingEnabled(privateBrowsingEnabled);
476 }
477 
setXSSAuditorEnabled(bool enabled)478 void LayoutTestController::setXSSAuditorEnabled(bool enabled)
479 {
480     COMPtr<IWebView> webView;
481     if (FAILED(frame->webView(&webView)))
482         return;
483 
484     COMPtr<IWebPreferences> preferences;
485     if (FAILED(webView->preferences(&preferences)))
486         return;
487 
488     COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
489     if (!prefsPrivate)
490         return;
491 
492     prefsPrivate->setXSSAuditorEnabled(enabled);
493 }
494 
setFrameFlatteningEnabled(bool enabled)495 void LayoutTestController::setFrameFlatteningEnabled(bool enabled)
496 {
497     COMPtr<IWebView> webView;
498     if (FAILED(frame->webView(&webView)))
499         return;
500 
501     COMPtr<IWebPreferences> preferences;
502     if (FAILED(webView->preferences(&preferences)))
503         return;
504 
505     COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
506     if (!prefsPrivate)
507         return;
508 
509     prefsPrivate->setFrameFlatteningEnabled(enabled);
510 }
511 
setSpatialNavigationEnabled(bool enabled)512 void LayoutTestController::setSpatialNavigationEnabled(bool enabled)
513 {
514     // FIXME: Implement for SpatialNavigation layout tests.
515 }
516 
setAllowUniversalAccessFromFileURLs(bool enabled)517 void LayoutTestController::setAllowUniversalAccessFromFileURLs(bool enabled)
518 {
519     COMPtr<IWebView> webView;
520     if (FAILED(frame->webView(&webView)))
521         return;
522 
523     COMPtr<IWebPreferences> preferences;
524     if (FAILED(webView->preferences(&preferences)))
525         return;
526 
527     COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
528     if (!prefsPrivate)
529         return;
530 
531     prefsPrivate->setAllowUniversalAccessFromFileURLs(enabled);
532 }
533 
setAllowFileAccessFromFileURLs(bool enabled)534 void LayoutTestController::setAllowFileAccessFromFileURLs(bool enabled)
535 {
536     COMPtr<IWebView> webView;
537     if (FAILED(frame->webView(&webView)))
538         return;
539 
540     COMPtr<IWebPreferences> preferences;
541     if (FAILED(webView->preferences(&preferences)))
542         return;
543 
544     COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
545     if (!prefsPrivate)
546         return;
547 
548     prefsPrivate->setAllowFileAccessFromFileURLs(enabled);
549 }
550 
setPopupBlockingEnabled(bool enabled)551 void LayoutTestController::setPopupBlockingEnabled(bool enabled)
552 {
553     COMPtr<IWebView> webView;
554     if (FAILED(frame->webView(&webView)))
555         return;
556 
557     COMPtr<IWebPreferences> preferences;
558     if (FAILED(webView->preferences(&preferences)))
559         return;
560 
561     preferences->setJavaScriptCanOpenWindowsAutomatically(!enabled);
562 }
563 
setPluginsEnabled(bool flag)564 void LayoutTestController::setPluginsEnabled(bool flag)
565 {
566     // FIXME: Implement
567 }
568 
setJavaScriptCanAccessClipboard(bool enabled)569 void LayoutTestController::setJavaScriptCanAccessClipboard(bool enabled)
570 {
571     COMPtr<IWebView> webView;
572     if (FAILED(frame->webView(&webView)))
573         return;
574 
575     COMPtr<IWebPreferences> preferences;
576     if (FAILED(webView->preferences(&preferences)))
577         return;
578 
579     COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
580     if (!prefsPrivate)
581         return;
582 
583     prefsPrivate->setJavaScriptCanAccessClipboard(enabled);
584 }
585 
setTabKeyCyclesThroughElements(bool shouldCycle)586 void LayoutTestController::setTabKeyCyclesThroughElements(bool shouldCycle)
587 {
588     COMPtr<IWebView> webView;
589     if (FAILED(frame->webView(&webView)))
590         return;
591 
592     COMPtr<IWebViewPrivate> viewPrivate;
593     if (FAILED(webView->QueryInterface(&viewPrivate)))
594         return;
595 
596     viewPrivate->setTabKeyCyclesThroughElements(shouldCycle ? TRUE : FALSE);
597 }
598 
setTimelineProfilingEnabled(bool flag)599 void LayoutTestController::setTimelineProfilingEnabled(bool flag)
600 {
601     COMPtr<IWebView> webView;
602     if (FAILED(frame->webView(&webView)))
603         return;
604 
605     COMPtr<IWebViewPrivate> viewPrivate;
606     if (FAILED(webView->QueryInterface(&viewPrivate)))
607         return;
608 
609     COMPtr<IWebInspector> inspector;
610     if (FAILED(viewPrivate->inspector(&inspector)))
611         return;
612 
613     inspector->setTimelineProfilingEnabled(flag);
614 }
615 
setUseDashboardCompatibilityMode(bool flag)616 void LayoutTestController::setUseDashboardCompatibilityMode(bool flag)
617 {
618     // FIXME: Implement!
619 }
620 
setUserStyleSheetEnabled(bool flag)621 void LayoutTestController::setUserStyleSheetEnabled(bool flag)
622 {
623     COMPtr<IWebView> webView;
624     if (FAILED(frame->webView(&webView)))
625         return;
626 
627     COMPtr<IWebPreferences> preferences;
628     if (FAILED(webView->preferences(&preferences)))
629         return;
630 
631    preferences->setUserStyleSheetEnabled(flag);
632 }
633 
appendComponentToPath(wstring & path,const wstring & component)634 bool appendComponentToPath(wstring& path, const wstring& component)
635 {
636     WCHAR buffer[MAX_PATH];
637 
638     if (path.size() + 1 > MAX_PATH)
639         return false;
640 
641     memcpy(buffer, path.data(), path.size() * sizeof(WCHAR));
642     buffer[path.size()] = '\0';
643 
644     if (!PathAppendW(buffer, component.c_str()))
645         return false;
646 
647     path = wstring(buffer);
648     return true;
649 }
650 
followShortcuts(wstring & path)651 static bool followShortcuts(wstring& path)
652 {
653     if (PathFileExists(path.c_str()))
654         return true;
655 
656     // Do we have a shortcut?
657     wstring linkPath = path;
658     linkPath.append(TEXT(".lnk"));
659     if (!PathFileExists(linkPath.c_str()))
660        return true;
661 
662     // We have a shortcut, find its target.
663     COMPtr<IShellLink> shortcut(Create, CLSID_ShellLink);
664     if (!shortcut)
665        return false;
666     COMPtr<IPersistFile> persistFile(Query, shortcut);
667     if (!shortcut)
668         return false;
669     if (FAILED(persistFile->Load(linkPath.c_str(), STGM_READ)))
670         return false;
671     if (FAILED(shortcut->Resolve(0, 0)))
672         return false;
673     WCHAR targetPath[MAX_PATH];
674     DWORD targetPathLen = _countof(targetPath);
675     if (FAILED(shortcut->GetPath(targetPath, targetPathLen, 0, 0)))
676         return false;
677     if (!PathFileExists(targetPath))
678         return false;
679     // Use the target path as the result path instead.
680     path = wstring(targetPath);
681 
682     return true;
683 }
684 
resolveCygwinPath(const wstring & cygwinPath,wstring & windowsPath)685 static bool resolveCygwinPath(const wstring& cygwinPath, wstring& windowsPath)
686 {
687     wstring fileProtocol = L"file://";
688     bool isFileProtocol = cygwinPath.find(fileProtocol) != string::npos;
689     if (cygwinPath[isFileProtocol ? 7 : 0] != '/')  // ensure path is absolute
690         return false;
691 
692     // Get the Root path.
693     WCHAR rootPath[MAX_PATH];
694     DWORD rootPathSize = _countof(rootPath);
695     DWORD keyType;
696     DWORD result = ::SHGetValueW(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Cygnus Solutions\\Cygwin\\mounts v2\\/"), TEXT("native"), &keyType, &rootPath, &rootPathSize);
697 
698     if (result != ERROR_SUCCESS || keyType != REG_SZ) {
699         // Cygwin 1.7 doesn't store Cygwin's root as a mount point anymore, because mount points are now stored in /etc/fstab.
700         // However, /etc/fstab doesn't contain any information about where / is located as a Windows path, so we need to use Cygwin's
701         // new registry key that has the root.
702         result = ::SHGetValueW(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Cygwin\\setup"), TEXT("rootdir"), &keyType, &rootPath, &rootPathSize);
703         if (result != ERROR_SUCCESS || keyType != REG_SZ)
704             return false;
705     }
706 
707     windowsPath = wstring(rootPath, rootPathSize);
708 
709     int oldPos = isFileProtocol ? 8 : 1;
710     while (1) {
711         int newPos = cygwinPath.find('/', oldPos);
712 
713         if (newPos == -1) {
714             wstring pathComponent = cygwinPath.substr(oldPos);
715 
716             if (!appendComponentToPath(windowsPath, pathComponent))
717                return false;
718 
719             if (!followShortcuts(windowsPath))
720                 return false;
721 
722             break;
723         }
724 
725         wstring pathComponent = cygwinPath.substr(oldPos, newPos - oldPos);
726         if (!appendComponentToPath(windowsPath, pathComponent))
727             return false;
728 
729         if (!followShortcuts(windowsPath))
730             return false;
731 
732         oldPos = newPos + 1;
733     }
734 
735     if (isFileProtocol)
736         windowsPath = fileProtocol + windowsPath;
737 
738     return true;
739 }
740 
setUserStyleSheetLocation(JSStringRef jsURL)741 void LayoutTestController::setUserStyleSheetLocation(JSStringRef jsURL)
742 {
743     COMPtr<IWebView> webView;
744     if (FAILED(frame->webView(&webView)))
745         return;
746 
747     COMPtr<IWebPreferences> preferences;
748     if (FAILED(webView->preferences(&preferences)))
749         return;
750 
751     RetainPtr<CFStringRef> urlString(AdoptCF, JSStringCopyCFString(0, jsURL));
752     RetainPtr<CFURLRef> url(AdoptCF, CFURLCreateWithString(0, urlString.get(), 0));
753     if (!url)
754         return;
755 
756     // Now copy the file system path, POSIX style.
757     RetainPtr<CFStringRef> pathCF(AdoptCF, CFURLCopyFileSystemPath(url.get(), kCFURLPOSIXPathStyle));
758     if (!pathCF)
759         return;
760 
761     wstring path = cfStringRefToWString(pathCF.get());
762 
763     wstring resultPath;
764     if (!resolveCygwinPath(path, resultPath))
765         return;
766 
767     // The path has been resolved, now convert it back to a CFURL.
768     int result = WideCharToMultiByte(CP_UTF8, 0, resultPath.c_str(), resultPath.size() + 1, 0, 0, 0, 0);
769     Vector<char> utf8Vector(result);
770     result = WideCharToMultiByte(CP_UTF8, 0, resultPath.c_str(), resultPath.size() + 1, utf8Vector.data(), result, 0, 0);
771     if (!result)
772         return;
773 
774     url = CFURLCreateFromFileSystemRepresentation(0, (const UInt8*)utf8Vector.data(), utf8Vector.size() - 1, false);
775     if (!url)
776         return;
777 
778     resultPath = cfStringRefToWString(CFURLGetString(url.get()));
779 
780     BSTR resultPathBSTR = SysAllocStringLen(resultPath.data(), resultPath.size());
781     preferences->setUserStyleSheetLocation(resultPathBSTR);
782     SysFreeString(resultPathBSTR);
783 }
784 
setValueForUser(JSContextRef context,JSValueRef element,JSStringRef value)785 void LayoutTestController::setValueForUser(JSContextRef context, JSValueRef element, JSStringRef value)
786 {
787     // FIXME: implement
788 }
789 
setViewModeMediaFeature(JSStringRef mode)790 void LayoutTestController::setViewModeMediaFeature(JSStringRef mode)
791 {
792     // FIXME: implement
793 }
794 
setPersistentUserStyleSheetLocation(JSStringRef jsURL)795 void LayoutTestController::setPersistentUserStyleSheetLocation(JSStringRef jsURL)
796 {
797     RetainPtr<CFStringRef> urlString(AdoptCF, JSStringCopyCFString(0, jsURL));
798     ::setPersistentUserStyleSheetLocation(urlString.get());
799 }
800 
clearPersistentUserStyleSheet()801 void LayoutTestController::clearPersistentUserStyleSheet()
802 {
803     ::setPersistentUserStyleSheetLocation(0);
804 }
805 
setWindowIsKey(bool flag)806 void LayoutTestController::setWindowIsKey(bool flag)
807 {
808     COMPtr<IWebView> webView;
809     if (FAILED(frame->webView(&webView)))
810         return;
811 
812     COMPtr<IWebViewPrivate> viewPrivate;
813     if (FAILED(webView->QueryInterface(&viewPrivate)))
814         return;
815 
816     HWND webViewWindow;
817     if (FAILED(viewPrivate->viewWindow((OLE_HANDLE*)&webViewWindow)))
818         return;
819 
820     ::SendMessage(webViewWindow, flag ? WM_SETFOCUS : WM_KILLFOCUS, (WPARAM)::GetDesktopWindow(), 0);
821 }
822 
setSmartInsertDeleteEnabled(bool flag)823 void LayoutTestController::setSmartInsertDeleteEnabled(bool flag)
824 {
825     COMPtr<IWebView> webView;
826     if (FAILED(frame->webView(&webView)))
827         return;
828 
829     COMPtr<IWebViewEditing> viewEditing;
830     if (FAILED(webView->QueryInterface(&viewEditing)))
831         return;
832 
833     viewEditing->setSmartInsertDeleteEnabled(flag ? TRUE : FALSE);
834 }
835 
setJavaScriptProfilingEnabled(bool flag)836 void LayoutTestController::setJavaScriptProfilingEnabled(bool flag)
837 {
838     COMPtr<IWebView> webView;
839     if (FAILED(frame->webView(&webView)))
840         return;
841 
842     COMPtr<IWebViewPrivate> viewPrivate;
843     if (FAILED(webView->QueryInterface(&viewPrivate)))
844         return;
845 
846     COMPtr<IWebInspector> inspector;
847     if (FAILED(viewPrivate->inspector(&inspector)))
848         return;
849 
850     setDeveloperExtrasEnabled(flag);
851     inspector->setJavaScriptProfilingEnabled(flag);
852 }
853 
setSelectTrailingWhitespaceEnabled(bool flag)854 void LayoutTestController::setSelectTrailingWhitespaceEnabled(bool flag)
855 {
856     COMPtr<IWebView> webView;
857     if (FAILED(frame->webView(&webView)))
858         return;
859 
860     COMPtr<IWebViewEditing> viewEditing;
861     if (FAILED(webView->QueryInterface(&viewEditing)))
862         return;
863 
864     viewEditing->setSelectTrailingWhitespaceEnabled(flag ? TRUE : FALSE);
865 }
866 
867 static const CFTimeInterval waitToDumpWatchdogInterval = 30.0;
868 
waitUntilDoneWatchdogFired(HWND,UINT,UINT_PTR,DWORD)869 static void CALLBACK waitUntilDoneWatchdogFired(HWND, UINT, UINT_PTR, DWORD)
870 {
871     gLayoutTestController->waitToDumpWatchdogTimerFired();
872 }
873 
setWaitToDump(bool waitUntilDone)874 void LayoutTestController::setWaitToDump(bool waitUntilDone)
875 {
876     m_waitToDump = waitUntilDone;
877     if (m_waitToDump && !waitToDumpWatchdog)
878         waitToDumpWatchdog = SetTimer(0, 0, waitToDumpWatchdogInterval * 1000, waitUntilDoneWatchdogFired);
879 }
880 
windowCount()881 int LayoutTestController::windowCount()
882 {
883     return openWindows().size();
884 }
885 
elementDoesAutoCompleteForElementWithId(JSStringRef id)886 bool LayoutTestController::elementDoesAutoCompleteForElementWithId(JSStringRef id)
887 {
888     COMPtr<IDOMDocument> document;
889     if (FAILED(frame->DOMDocument(&document)))
890         return false;
891 
892     wstring idWstring = jsStringRefToWString(id);
893     BSTR idBSTR = SysAllocStringLen((OLECHAR*)idWstring.c_str(), idWstring.length());
894     COMPtr<IDOMElement> element;
895     HRESULT result = document->getElementById(idBSTR, &element);
896     SysFreeString(idBSTR);
897 
898     if (FAILED(result))
899         return false;
900 
901     COMPtr<IWebFramePrivate> framePrivate(Query, frame);
902     if (!framePrivate)
903         return false;
904 
905     BOOL autoCompletes;
906     if (FAILED(framePrivate->elementDoesAutoComplete(element.get(), &autoCompletes)))
907         return false;
908 
909     return autoCompletes;
910 }
911 
execCommand(JSStringRef name,JSStringRef value)912 void LayoutTestController::execCommand(JSStringRef name, JSStringRef value)
913 {
914     wstring wName = jsStringRefToWString(name);
915     wstring wValue = jsStringRefToWString(value);
916 
917     COMPtr<IWebView> webView;
918     if (FAILED(frame->webView(&webView)))
919         return;
920 
921     COMPtr<IWebViewPrivate> viewPrivate;
922     if (FAILED(webView->QueryInterface(&viewPrivate)))
923         return;
924 
925     BSTR nameBSTR = SysAllocStringLen((OLECHAR*)wName.c_str(), wName.length());
926     BSTR valueBSTR = SysAllocStringLen((OLECHAR*)wValue.c_str(), wValue.length());
927     viewPrivate->executeCoreCommandByName(nameBSTR, valueBSTR);
928 
929     SysFreeString(nameBSTR);
930     SysFreeString(valueBSTR);
931 }
932 
findString(JSContextRef,JSStringRef,JSObjectRef)933 bool LayoutTestController::findString(JSContextRef /* context */, JSStringRef /* target */, JSObjectRef /* optionsArray */)
934 {
935     // FIXME: Implement
936     return false;
937 }
938 
setCacheModel(int)939 void LayoutTestController::setCacheModel(int)
940 {
941     // FIXME: Implement
942 }
943 
isCommandEnabled(JSStringRef)944 bool LayoutTestController::isCommandEnabled(JSStringRef /*name*/)
945 {
946     printf("ERROR: LayoutTestController::isCommandEnabled() not implemented\n");
947     return false;
948 }
949 
clearAllApplicationCaches()950 void LayoutTestController::clearAllApplicationCaches()
951 {
952     // FIXME: Implement to support application cache quotas.
953 }
954 
clearApplicationCacheForOrigin(JSStringRef origin)955 void LayoutTestController::clearApplicationCacheForOrigin(JSStringRef origin)
956 {
957     // FIXME: Implement to support deleting all application cache for an origin.
958 }
959 
setApplicationCacheOriginQuota(unsigned long long quota)960 void LayoutTestController::setApplicationCacheOriginQuota(unsigned long long quota)
961 {
962     // FIXME: Implement to support application cache quotas.
963 }
964 
originsWithApplicationCache(JSContextRef context)965 JSValueRef LayoutTestController::originsWithApplicationCache(JSContextRef context)
966 {
967     // FIXME: Implement to get origins that have application caches.
968     return JSValueMakeUndefined(context);
969 }
970 
clearAllDatabases()971 void LayoutTestController::clearAllDatabases()
972 {
973     COMPtr<IWebDatabaseManager> databaseManager;
974     COMPtr<IWebDatabaseManager> tmpDatabaseManager;
975     if (FAILED(WebKitCreateInstance(CLSID_WebDatabaseManager, 0, IID_IWebDatabaseManager, (void**)&tmpDatabaseManager)))
976         return;
977     if (FAILED(tmpDatabaseManager->sharedWebDatabaseManager(&databaseManager)))
978         return;
979 
980     databaseManager->deleteAllDatabases();
981 }
982 
overridePreference(JSStringRef key,JSStringRef value)983 void LayoutTestController::overridePreference(JSStringRef key, JSStringRef value)
984 {
985     COMPtr<IWebView> webView;
986     if (FAILED(frame->webView(&webView)))
987         return;
988 
989     COMPtr<IWebPreferences> preferences;
990     if (FAILED(webView->preferences(&preferences)))
991         return;
992 
993     COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
994     if (!prefsPrivate)
995         return;
996 
997     BSTR keyBSTR = JSStringCopyBSTR(key);
998     BSTR valueBSTR = JSStringCopyBSTR(value);
999     prefsPrivate->setPreferenceForTest(keyBSTR, valueBSTR);
1000     SysFreeString(keyBSTR);
1001     SysFreeString(valueBSTR);
1002 }
1003 
setDatabaseQuota(unsigned long long quota)1004 void LayoutTestController::setDatabaseQuota(unsigned long long quota)
1005 {
1006     COMPtr<IWebDatabaseManager> databaseManager;
1007     COMPtr<IWebDatabaseManager> tmpDatabaseManager;
1008 
1009     if (FAILED(WebKitCreateInstance(CLSID_WebDatabaseManager, 0, IID_IWebDatabaseManager, (void**)&tmpDatabaseManager)))
1010         return;
1011     if (FAILED(tmpDatabaseManager->sharedWebDatabaseManager(&databaseManager)))
1012         return;
1013 
1014     databaseManager->setQuota(TEXT("file:///"), quota);
1015 }
1016 
setDomainRelaxationForbiddenForURLScheme(bool forbidden,JSStringRef scheme)1017 void LayoutTestController::setDomainRelaxationForbiddenForURLScheme(bool forbidden, JSStringRef scheme)
1018 {
1019     COMPtr<IWebViewPrivate> webView;
1020     if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView))))
1021         return;
1022 
1023     BSTR schemeBSTR = JSStringCopyBSTR(scheme);
1024     webView->setDomainRelaxationForbiddenForURLScheme(forbidden, schemeBSTR);
1025     SysFreeString(schemeBSTR);
1026 }
1027 
setAppCacheMaximumSize(unsigned long long size)1028 void LayoutTestController::setAppCacheMaximumSize(unsigned long long size)
1029 {
1030     printf("ERROR: LayoutTestController::setAppCacheMaximumSize() not implemented\n");
1031 }
1032 
pauseAnimationAtTimeOnElementWithId(JSStringRef animationName,double time,JSStringRef elementId)1033 bool LayoutTestController::pauseAnimationAtTimeOnElementWithId(JSStringRef animationName, double time, JSStringRef elementId)
1034 {
1035     COMPtr<IDOMDocument> document;
1036     if (FAILED(frame->DOMDocument(&document)))
1037         return false;
1038 
1039     BSTR idBSTR = JSStringCopyBSTR(elementId);
1040     COMPtr<IDOMElement> element;
1041     HRESULT hr = document->getElementById(idBSTR, &element);
1042     SysFreeString(idBSTR);
1043     if (FAILED(hr))
1044         return false;
1045 
1046     COMPtr<IWebFramePrivate> framePrivate(Query, frame);
1047     if (!framePrivate)
1048         return false;
1049 
1050     BSTR nameBSTR = JSStringCopyBSTR(animationName);
1051     BOOL wasRunning = FALSE;
1052     hr = framePrivate->pauseAnimation(nameBSTR, element.get(), time, &wasRunning);
1053     SysFreeString(nameBSTR);
1054 
1055     return SUCCEEDED(hr) && wasRunning;
1056 }
1057 
pauseTransitionAtTimeOnElementWithId(JSStringRef propertyName,double time,JSStringRef elementId)1058 bool LayoutTestController::pauseTransitionAtTimeOnElementWithId(JSStringRef propertyName, double time, JSStringRef elementId)
1059 {
1060     COMPtr<IDOMDocument> document;
1061     if (FAILED(frame->DOMDocument(&document)))
1062         return false;
1063 
1064     BSTR idBSTR = JSStringCopyBSTR(elementId);
1065     COMPtr<IDOMElement> element;
1066     HRESULT hr = document->getElementById(idBSTR, &element);
1067     SysFreeString(idBSTR);
1068     if (FAILED(hr))
1069         return false;
1070 
1071     COMPtr<IWebFramePrivate> framePrivate(Query, frame);
1072     if (!framePrivate)
1073         return false;
1074 
1075     BSTR nameBSTR = JSStringCopyBSTR(propertyName);
1076     BOOL wasRunning = FALSE;
1077     hr = framePrivate->pauseTransition(nameBSTR, element.get(), time, &wasRunning);
1078     SysFreeString(nameBSTR);
1079 
1080     return SUCCEEDED(hr) && wasRunning;
1081 }
1082 
sampleSVGAnimationForElementAtTime(JSStringRef animationId,double time,JSStringRef elementId)1083 bool LayoutTestController::sampleSVGAnimationForElementAtTime(JSStringRef animationId, double time, JSStringRef elementId)
1084 {
1085     COMPtr<IDOMDocument> document;
1086     if (FAILED(frame->DOMDocument(&document)))
1087         return false;
1088 
1089     BSTR idBSTR = JSStringCopyBSTR(animationId);
1090     COMPtr<IDOMElement> element;
1091     HRESULT hr = document->getElementById(idBSTR, &element);
1092     SysFreeString(idBSTR);
1093     if (FAILED(hr))
1094         return false;
1095 
1096     COMPtr<IWebFramePrivate> framePrivate(Query, frame);
1097     if (!framePrivate)
1098         return false;
1099 
1100     BSTR elementIdBSTR = JSStringCopyBSTR(elementId);
1101     BOOL wasRunning = FALSE;
1102     hr = framePrivate->pauseSVGAnimation(elementIdBSTR, element.get(), time, &wasRunning);
1103     SysFreeString(elementIdBSTR);
1104 
1105     return SUCCEEDED(hr) && wasRunning;
1106 }
1107 
numberOfActiveAnimations() const1108 unsigned LayoutTestController::numberOfActiveAnimations() const
1109 {
1110     COMPtr<IWebFramePrivate> framePrivate(Query, frame);
1111     if (!framePrivate)
1112         return 0;
1113 
1114     UINT number = 0;
1115     if (FAILED(framePrivate->numberOfActiveAnimations(&number)))
1116         return 0;
1117 
1118     return number;
1119 }
1120 
suspendAnimations() const1121 void LayoutTestController::suspendAnimations() const
1122 {
1123     COMPtr<IWebFramePrivate> framePrivate(Query, frame);
1124     if (!framePrivate)
1125         return;
1126 
1127     framePrivate->suspendAnimations();
1128 }
1129 
resumeAnimations() const1130 void LayoutTestController::resumeAnimations() const
1131 {
1132     COMPtr<IWebFramePrivate> framePrivate(Query, frame);
1133     if (!framePrivate)
1134         return;
1135 
1136     framePrivate->resumeAnimations();
1137 }
1138 
bstrT(JSStringRef jsString)1139 static _bstr_t bstrT(JSStringRef jsString)
1140 {
1141     // The false parameter tells the _bstr_t constructor to adopt the BSTR we pass it.
1142     return _bstr_t(JSStringCopyBSTR(jsString), false);
1143 }
1144 
addOriginAccessWhitelistEntry(JSStringRef sourceOrigin,JSStringRef destinationProtocol,JSStringRef destinationHost,bool allowDestinationSubdomains)1145 void LayoutTestController::addOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains)
1146 {
1147     COMPtr<IWebViewPrivate> webView;
1148     if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView))))
1149         return;
1150 
1151     webView->addOriginAccessWhitelistEntry(bstrT(sourceOrigin).GetBSTR(), bstrT(destinationProtocol).GetBSTR(), bstrT(destinationHost).GetBSTR(), allowDestinationSubdomains);
1152 }
1153 
removeOriginAccessWhitelistEntry(JSStringRef sourceOrigin,JSStringRef destinationProtocol,JSStringRef destinationHost,bool allowDestinationSubdomains)1154 void LayoutTestController::removeOriginAccessWhitelistEntry(JSStringRef sourceOrigin, JSStringRef destinationProtocol, JSStringRef destinationHost, bool allowDestinationSubdomains)
1155 {
1156     COMPtr<IWebViewPrivate> webView;
1157     if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView))))
1158         return;
1159 
1160     webView->removeOriginAccessWhitelistEntry(bstrT(sourceOrigin).GetBSTR(), bstrT(destinationProtocol).GetBSTR(), bstrT(destinationHost).GetBSTR(), allowDestinationSubdomains);
1161 }
1162 
setScrollbarPolicy(JSStringRef orientation,JSStringRef policy)1163 void LayoutTestController::setScrollbarPolicy(JSStringRef orientation, JSStringRef policy)
1164 {
1165     // FIXME: implement
1166 }
1167 
addUserScript(JSStringRef source,bool runAtStart,bool allFrames)1168 void LayoutTestController::addUserScript(JSStringRef source, bool runAtStart, bool allFrames)
1169 {
1170     COMPtr<IWebViewPrivate> webView;
1171     if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView))))
1172         return;
1173 
1174     COMPtr<IWebScriptWorld> world;
1175     if (FAILED(WebKitCreateInstance(__uuidof(WebScriptWorld), 0, __uuidof(world), reinterpret_cast<void**>(&world))))
1176         return;
1177 
1178     webView->addUserScriptToGroup(_bstr_t(L"org.webkit.DumpRenderTree").GetBSTR(), world.get(), bstrT(source).GetBSTR(), 0, 0, 0, 0, 0, runAtStart ? WebInjectAtDocumentStart : WebInjectAtDocumentEnd);
1179 }
1180 
1181 
addUserStyleSheet(JSStringRef source,bool allFrames)1182 void LayoutTestController::addUserStyleSheet(JSStringRef source, bool allFrames)
1183 {
1184     COMPtr<IWebViewPrivate> webView;
1185     if (FAILED(WebKitCreateInstance(__uuidof(WebView), 0, __uuidof(webView), reinterpret_cast<void**>(&webView))))
1186         return;
1187 
1188     COMPtr<IWebScriptWorld> world;
1189     if (FAILED(WebKitCreateInstance(__uuidof(WebScriptWorld), 0, __uuidof(world), reinterpret_cast<void**>(&world))))
1190         return;
1191 
1192     webView->addUserStyleSheetToGroup(_bstr_t(L"org.webkit.DumpRenderTree").GetBSTR(), world.get(), bstrT(source).GetBSTR(), 0, 0, 0, 0, 0);
1193 }
1194 
setDeveloperExtrasEnabled(bool enabled)1195 void LayoutTestController::setDeveloperExtrasEnabled(bool enabled)
1196 {
1197     COMPtr<IWebView> webView;
1198     if (FAILED(frame->webView(&webView)))
1199         return;
1200 
1201     COMPtr<IWebPreferences> preferences;
1202     if (FAILED(webView->preferences(&preferences)))
1203         return;
1204 
1205     COMPtr<IWebPreferencesPrivate> prefsPrivate(Query, preferences);
1206     if (!prefsPrivate)
1207         return;
1208 
1209     prefsPrivate->setDeveloperExtrasEnabled(enabled);
1210 }
1211 
setAsynchronousSpellCheckingEnabled(bool)1212 void LayoutTestController::setAsynchronousSpellCheckingEnabled(bool)
1213 {
1214     // FIXME: Implement this.
1215 }
1216 
showWebInspector()1217 void LayoutTestController::showWebInspector()
1218 {
1219     COMPtr<IWebView> webView;
1220     if (FAILED(frame->webView(&webView)))
1221         return;
1222 
1223     COMPtr<IWebViewPrivate> viewPrivate(Query, webView);
1224     if (!viewPrivate)
1225         return;
1226 
1227     COMPtr<IWebInspector> inspector;
1228     if (SUCCEEDED(viewPrivate->inspector(&inspector)))
1229         inspector->show();
1230 }
1231 
closeWebInspector()1232 void LayoutTestController::closeWebInspector()
1233 {
1234     COMPtr<IWebView> webView;
1235     if (FAILED(frame->webView(&webView)))
1236         return;
1237 
1238     COMPtr<IWebViewPrivate> viewPrivate(Query, webView);
1239     if (!viewPrivate)
1240         return;
1241 
1242     COMPtr<IWebInspector> inspector;
1243     if (FAILED(viewPrivate->inspector(&inspector)))
1244         return;
1245 
1246     inspector->close();
1247 }
1248 
evaluateInWebInspector(long callId,JSStringRef script)1249 void LayoutTestController::evaluateInWebInspector(long callId, JSStringRef script)
1250 {
1251     COMPtr<IWebView> webView;
1252     if (FAILED(frame->webView(&webView)))
1253         return;
1254 
1255     COMPtr<IWebViewPrivate> viewPrivate(Query, webView);
1256     if (!viewPrivate)
1257         return;
1258 
1259     COMPtr<IWebInspector> inspector;
1260     if (FAILED(viewPrivate->inspector(&inspector)))
1261         return;
1262 
1263     COMPtr<IWebInspectorPrivate> inspectorPrivate(Query, inspector);
1264     if (!inspectorPrivate)
1265         return;
1266 
1267     inspectorPrivate->evaluateInFrontend(callId, bstrT(script).GetBSTR());
1268 }
1269 
1270 typedef HashMap<unsigned, COMPtr<IWebScriptWorld> > WorldMap;
worldMap()1271 static WorldMap& worldMap()
1272 {
1273     static WorldMap& map = *new WorldMap;
1274     return map;
1275 }
1276 
worldIDForWorld(IWebScriptWorld * world)1277 unsigned worldIDForWorld(IWebScriptWorld* world)
1278 {
1279     WorldMap::const_iterator end = worldMap().end();
1280     for (WorldMap::const_iterator it = worldMap().begin(); it != end; ++it) {
1281         if (it->second == world)
1282             return it->first;
1283     }
1284 
1285     return 0;
1286 }
1287 
evaluateScriptInIsolatedWorld(unsigned worldID,JSObjectRef globalObject,JSStringRef script)1288 void LayoutTestController::evaluateScriptInIsolatedWorld(unsigned worldID, JSObjectRef globalObject, JSStringRef script)
1289 {
1290     COMPtr<IWebFramePrivate> framePrivate(Query, frame);
1291     if (!framePrivate)
1292         return;
1293 
1294     // A worldID of 0 always corresponds to a new world. Any other worldID corresponds to a world
1295     // that is created once and cached forever.
1296     COMPtr<IWebScriptWorld> world;
1297     if (!worldID) {
1298         if (FAILED(WebKitCreateInstance(__uuidof(WebScriptWorld), 0, __uuidof(world), reinterpret_cast<void**>(&world))))
1299             return;
1300     } else {
1301         COMPtr<IWebScriptWorld>& worldSlot = worldMap().add(worldID, 0).first->second;
1302         if (!worldSlot && FAILED(WebKitCreateInstance(__uuidof(WebScriptWorld), 0, __uuidof(worldSlot), reinterpret_cast<void**>(&worldSlot))))
1303             return;
1304         world = worldSlot;
1305     }
1306 
1307     BSTR result;
1308     if (FAILED(framePrivate->stringByEvaluatingJavaScriptInScriptWorld(world.get(), globalObject, bstrT(script).GetBSTR(), &result)))
1309         return;
1310     SysFreeString(result);
1311 }
1312 
removeAllVisitedLinks()1313 void LayoutTestController::removeAllVisitedLinks()
1314 {
1315     COMPtr<IWebHistory> history;
1316     if (FAILED(WebKitCreateInstance(CLSID_WebHistory, 0, __uuidof(history), reinterpret_cast<void**>(&history))))
1317         return;
1318 
1319     COMPtr<IWebHistory> sharedHistory;
1320     if (FAILED(history->optionalSharedHistory(&sharedHistory)) || !sharedHistory)
1321         return;
1322 
1323     COMPtr<IWebHistoryPrivate> sharedHistoryPrivate;
1324     if (FAILED(sharedHistory->QueryInterface(&sharedHistoryPrivate)))
1325         return;
1326 
1327     sharedHistoryPrivate->removeAllVisitedLinks();
1328 }
1329 
counterValueForElementById(JSStringRef id)1330 JSRetainPtr<JSStringRef> LayoutTestController::counterValueForElementById(JSStringRef id)
1331 {
1332     COMPtr<IWebFramePrivate> framePrivate(Query, frame);
1333     if (!framePrivate)
1334         return 0;
1335 
1336     wstring idWstring = jsStringRefToWString(id);
1337     BSTR idBSTR = SysAllocStringLen((OLECHAR*)idWstring.c_str(), idWstring.length());
1338     BSTR counterValueBSTR;
1339     if (FAILED(framePrivate->counterValueForElementById(idBSTR, &counterValueBSTR)))
1340         return 0;
1341 
1342     wstring counterValue(counterValueBSTR, SysStringLen(counterValueBSTR));
1343     SysFreeString(idBSTR);
1344     SysFreeString(counterValueBSTR);
1345     JSRetainPtr<JSStringRef> counterValueJS(Adopt, JSStringCreateWithCharacters(counterValue.data(), counterValue.length()));
1346     return counterValueJS;
1347 }
1348 
pageNumberForElementById(JSStringRef id,float pageWidthInPixels,float pageHeightInPixels)1349 int LayoutTestController::pageNumberForElementById(JSStringRef id, float pageWidthInPixels, float pageHeightInPixels)
1350 {
1351     COMPtr<IWebFramePrivate> framePrivate(Query, frame);
1352     if (!framePrivate)
1353         return 0;
1354 
1355     wstring idWstring = jsStringRefToWString(id);
1356     BSTR idBSTR = SysAllocStringLen((OLECHAR*)idWstring.c_str(), idWstring.length());
1357     int pageNumber = -1;
1358     if (FAILED(framePrivate->pageNumberForElementById(idBSTR, pageWidthInPixels, pageHeightInPixels, &pageNumber)))
1359         pageNumber = -1;
1360     SysFreeString(idBSTR);
1361     return pageNumber;
1362 }
1363 
numberOfPages(float pageWidthInPixels,float pageHeightInPixels)1364 int LayoutTestController::numberOfPages(float pageWidthInPixels, float pageHeightInPixels)
1365 {
1366     COMPtr<IWebFramePrivate> framePrivate(Query, frame);
1367     if (!framePrivate)
1368         return 0;
1369 
1370     int pageNumber = -1;
1371     if (FAILED(framePrivate->numberOfPages(pageWidthInPixels, pageHeightInPixels, &pageNumber)))
1372         pageNumber = -1;
1373     return pageNumber;
1374 }
1375 
pageProperty(const char * propertyName,int pageNumber) const1376 JSRetainPtr<JSStringRef> LayoutTestController::pageProperty(const char* propertyName, int pageNumber) const
1377 {
1378     // FIXME: Implement this.
1379     return JSRetainPtr<JSStringRef>();
1380 }
1381 
apiTestNewWindowDataLoadBaseURL(JSStringRef utf8Data,JSStringRef baseURL)1382 void LayoutTestController::apiTestNewWindowDataLoadBaseURL(JSStringRef utf8Data, JSStringRef baseURL)
1383 {
1384 
1385 }
1386 
isPageBoxVisible(int pageNumber) const1387 bool LayoutTestController::isPageBoxVisible(int pageNumber) const
1388 {
1389     // FIXME: implement
1390     return false;
1391 }
1392 
pageSizeAndMarginsInPixels(int pageNumber,int width,int height,int marginTop,int marginRight,int marginBottom,int marginLeft) const1393 JSRetainPtr<JSStringRef> LayoutTestController::pageSizeAndMarginsInPixels(int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft) const
1394 {
1395     // FIXME: implement
1396     return JSRetainPtr<JSStringRef>();
1397 }
1398 
apiTestGoToCurrentBackForwardItem()1399 void LayoutTestController::apiTestGoToCurrentBackForwardItem()
1400 {
1401     COMPtr<IWebView> webView;
1402     if (FAILED(frame->webView(&webView)))
1403         return;
1404 
1405     COMPtr<IWebBackForwardList> backForwardList;
1406     if (FAILED(webView->backForwardList(&backForwardList)))
1407         return;
1408 
1409     COMPtr<IWebHistoryItem> item;
1410     if (FAILED(backForwardList->currentItem(&item)))
1411         return;
1412 
1413     BOOL success;
1414     webView->goToBackForwardItem(item.get(), &success);
1415 }
1416 
setWebViewEditable(bool)1417 void LayoutTestController::setWebViewEditable(bool)
1418 {
1419 }
1420 
authenticateSession(JSStringRef,JSStringRef,JSStringRef)1421 void LayoutTestController::authenticateSession(JSStringRef, JSStringRef, JSStringRef)
1422 {
1423 }
1424 
setEditingBehavior(const char * editingBehavior)1425 void LayoutTestController::setEditingBehavior(const char* editingBehavior)
1426 {
1427     COMPtr<IWebView> webView;
1428     if (FAILED(frame->webView(&webView)))
1429         return;
1430 
1431     COMPtr<IWebPreferences> preferences;
1432     if (FAILED(webView->preferences(&preferences)))
1433         return;
1434 
1435     string behaviorString(editingBehavior);
1436     if (behaviorString == "mac")
1437         preferences->setEditingBehavior(WebKitEditingMacBehavior);
1438     else if (behaviorString == "win")
1439         preferences->setEditingBehavior(WebKitEditingWinBehavior);
1440     else if (behaviorString == "unix")
1441         preferences->setEditingBehavior(WebKitEditingUnixBehavior);
1442 }
1443 
shadowRoot(JSContextRef context,JSValueRef jsElement)1444 JSValueRef LayoutTestController::shadowRoot(JSContextRef context, JSValueRef jsElement)
1445 {
1446     // FIXME: Implement this.
1447     return JSValueMakeUndefined(context);
1448 }
1449 
abortModal()1450 void LayoutTestController::abortModal()
1451 {
1452 }
1453 
hasSpellingMarker(int from,int length)1454 bool LayoutTestController::hasSpellingMarker(int from, int length)
1455 {
1456     COMPtr<IWebFramePrivate> framePrivate(Query, frame);
1457     if (!framePrivate)
1458         return false;
1459     BOOL ret = FALSE;
1460     if (FAILED(framePrivate->hasSpellingMarker(from, length, &ret)))
1461         return false;
1462     return ret;
1463 }
1464 
hasGrammarMarker(int from,int length)1465 bool LayoutTestController::hasGrammarMarker(int from, int length)
1466 {
1467     // FIXME: Implement this.
1468     return false;
1469 }
1470 
dumpConfigurationForViewport(int,int,int,int,int)1471 void LayoutTestController::dumpConfigurationForViewport(int /*deviceDPI*/, int /*deviceWidth*/, int /*deviceHeight*/, int /*availableWidth*/, int /*availableHeight*/)
1472 {
1473     // FIXME: Implement this.
1474 }
1475 
setSerializeHTTPLoads(bool)1476 void LayoutTestController::setSerializeHTTPLoads(bool)
1477 {
1478     // FIXME: Implement.
1479 }
1480 
syncLocalStorage()1481 void LayoutTestController::syncLocalStorage()
1482 {
1483     // FIXME: Implement.
1484 }
1485 
observeStorageTrackerNotifications(unsigned number)1486 void LayoutTestController::observeStorageTrackerNotifications(unsigned number)
1487 {
1488     // FIXME: Implement.
1489 }
1490 
deleteAllLocalStorage()1491 void LayoutTestController::deleteAllLocalStorage()
1492 {
1493     // FIXME: Implement.
1494 }
1495 
originsWithLocalStorage(JSContextRef context)1496 JSValueRef LayoutTestController::originsWithLocalStorage(JSContextRef context)
1497 {
1498     // FIXME: Implement.
1499     return JSValueMakeUndefined(context);
1500 }
1501 
deleteLocalStorageForOrigin(JSStringRef URL)1502 void LayoutTestController::deleteLocalStorageForOrigin(JSStringRef URL)
1503 {
1504     // FIXME: Implement.
1505 }
1506 
setMinimumTimerInterval(double minimumTimerInterval)1507 void LayoutTestController::setMinimumTimerInterval(double minimumTimerInterval)
1508 {
1509     COMPtr<IWebView> webView;
1510     if (FAILED(frame->webView(&webView)))
1511         return;
1512 
1513     COMPtr<IWebViewPrivate> viewPrivate(Query, webView);
1514     if (!viewPrivate)
1515         return;
1516 
1517     viewPrivate->setMinimumTimerInterval(minimumTimerInterval);
1518 }
1519 
1520 
1521