1/*
2 * Copyright (C) 2007, 2009 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 "WorkQueueItem.h"
31
32#include "DumpRenderTree.h"
33#include <WebCore/COMPtr.h>
34#include <WebKit/WebKit.h>
35#include <WebKit/WebKitCOMAPI.h>
36#include <JavaScriptCore/JSStringRef.h>
37#include <JavaScriptCore/JSStringRefCF.h>
38#include <JavaScriptCore/RetainPtr.h>
39#include <wtf/Vector.h>
40#include <string>
41
42using std::wstring;
43
44static wstring jsStringRefToWString(JSStringRef jsStr)
45{
46    size_t length = JSStringGetLength(jsStr);
47    Vector<WCHAR> buffer(length + 1);
48    memcpy(buffer.data(), JSStringGetCharactersPtr(jsStr), length * sizeof(WCHAR));
49    buffer[length] = '\0';
50
51    return buffer.data();
52}
53
54bool LoadItem::invoke() const
55{
56    wstring targetString = jsStringRefToWString(m_target.get());
57
58    COMPtr<IWebFrame> targetFrame;
59    if (targetString.empty())
60        targetFrame = frame;
61    else {
62        BSTR targetBSTR = SysAllocString(targetString.c_str());
63        bool failed = FAILED(frame->findFrameNamed(targetBSTR, &targetFrame));
64        SysFreeString(targetBSTR);
65        if (failed)
66            return false;
67    }
68
69    COMPtr<IWebURLRequest> request;
70    if (FAILED(WebKitCreateInstance(CLSID_WebURLRequest, 0, IID_IWebURLRequest, (void**)&request)))
71        return false;
72
73    wstring urlString = jsStringRefToWString(m_url.get());
74    BSTR urlBSTR = SysAllocString(urlString.c_str());
75    bool failed = FAILED(request->initWithURL(urlBSTR, WebURLRequestUseProtocolCachePolicy, 60));
76    SysFreeString(urlBSTR);
77    if (failed)
78        return false;
79
80    targetFrame->loadRequest(request.get());
81    return true;
82}
83
84bool LoadHTMLStringItem::invoke() const
85{
86    wstring content = jsStringRefToWString(m_content.get());
87    wstring baseURL = jsStringRefToWString(m_baseURL.get());
88
89    BSTR contentBSTR = SysAllocString(content.c_str());
90    BSTR baseURLBSTR = SysAllocString(baseURL.c_str());
91
92    if (m_unreachableURL) {
93        wstring unreachableURL = jsStringRefToWString(m_unreachableURL.get());
94        BSTR unreachableURLBSTR = SysAllocString(unreachableURL.c_str());
95        frame->loadAlternateHTMLString(contentBSTR, baseURLBSTR, unreachableURLBSTR);
96        SysFreeString(contentBSTR);
97        SysFreeString(baseURLBSTR);
98        SysFreeString(unreachableURLBSTR);
99        return true;
100    }
101
102    frame->loadHTMLString(contentBSTR, baseURLBSTR);
103
104    SysFreeString(contentBSTR);
105    SysFreeString(baseURLBSTR);
106
107    return true;
108}
109
110bool ReloadItem::invoke() const
111{
112    COMPtr<IWebView> webView;
113    if (FAILED(frame->webView(&webView)))
114        return false;
115
116    COMPtr<IWebIBActions> webActions;
117    if (FAILED(webView->QueryInterface(&webActions)))
118        return false;
119
120    webActions->reload(0);
121    return true;
122}
123
124bool ScriptItem::invoke() const
125{
126    COMPtr<IWebView> webView;
127    if (FAILED(frame->webView(&webView)))
128        return false;
129
130    wstring scriptString = jsStringRefToWString(m_script.get());
131
132    BSTR result;
133    BSTR scriptBSTR = SysAllocString(scriptString.c_str());
134    webView->stringByEvaluatingJavaScriptFromString(scriptBSTR, &result);
135    SysFreeString(result);
136    SysFreeString(scriptBSTR);
137
138    return true;
139}
140
141bool BackForwardItem::invoke() const
142{
143    COMPtr<IWebView> webView;
144    if (FAILED(frame->webView(&webView)))
145        return false;
146
147    BOOL result;
148    if (m_howFar == 1) {
149        webView->goForward(&result);
150        return true;
151    }
152
153    if (m_howFar == -1) {
154        webView->goBack(&result);
155        return true;
156    }
157
158    COMPtr<IWebBackForwardList> bfList;
159    if (FAILED(webView->backForwardList(&bfList)))
160        return false;
161
162    COMPtr<IWebHistoryItem> item;
163    if (FAILED(bfList->itemAtIndex(m_howFar, &item)))
164        return false;
165
166    webView->goToBackForwardItem(item.get(), &result);
167    return true;
168}
169