~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionBasic_Bundle.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2012 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
 * 1. Redistributions of source code must retain the above copyright
 
8
 *    notice, this list of conditions and the following disclaimer.
 
9
 * 2. Redistributions in binary form must reproduce the above copyright
 
10
 *    notice, this list of conditions and the following disclaimer in the
 
11
 *    documentation and/or other materials provided with the distribution.
 
12
 *
 
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 
14
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 
15
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
16
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 
17
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
19
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
20
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
21
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
22
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 
23
 * THE POSSIBILITY OF SUCH DAMAGE.
 
24
 */
 
25
 
 
26
#include "config.h"
 
27
#include "InjectedBundleTest.h"
 
28
#include <WebKit2/WKBundleDOMWindowExtension.h>
 
29
#include <WebKit2/WKBundleFrame.h>
 
30
#include <WebKit2/WKBundlePage.h>
 
31
#include <WebKit2/WKBundlePageGroup.h>
 
32
#include <WebKit2/WKBundlePrivate.h>
 
33
#include <WebKit2/WKBundleScriptWorld.h>
 
34
#include <WebKit2/WKRetainPtr.h>
 
35
#include <wtf/HashMap.h>
 
36
#include <assert.h>
 
37
 
 
38
namespace TestWebKitAPI {
 
39
 
 
40
static void didFinishLoadForFrameCallback(WKBundlePageRef, WKBundleFrameRef, WKTypeRef*, const void* clientInfo);
 
41
static void globalObjectIsAvailableForFrameCallback(WKBundlePageRef, WKBundleFrameRef, WKBundleScriptWorldRef, const void* clientInfo);
 
42
static void willDisconnectDOMWindowExtensionFromGlobalObjectCallback(WKBundlePageRef, WKBundleDOMWindowExtensionRef, const void* clientInfo);
 
43
static void didReconnectDOMWindowExtensionToGlobalObjectCallback(WKBundlePageRef, WKBundleDOMWindowExtensionRef, const void* clientInfo);
 
44
static void willDestroyGlobalObjectForDOMWindowExtensionCallback(WKBundlePageRef, WKBundleDOMWindowExtensionRef, const void* clientInfo);
 
45
 
 
46
 
 
47
enum ExtensionState {
 
48
    Uncreated = 0, Connected, Disconnected, Destroyed, Removed
 
49
};
 
50
 
 
51
const char* stateNames[5] = {
 
52
    "Uncreated",
 
53
    "Connected",
 
54
    "Disconnected",
 
55
    "Destroyed",
 
56
    "Removed"
 
57
};
 
58
 
 
59
typedef struct {
 
60
    const char* name;
 
61
    ExtensionState state;
 
62
} ExtensionRecord;
 
63
    
 
64
class DOMWindowExtensionBasic : public InjectedBundleTest {
 
65
public:
 
66
    DOMWindowExtensionBasic(const std::string& identifier);
 
67
    
 
68
    virtual void initialize(WKBundleRef, WKTypeRef userData);
 
69
    virtual void didCreatePage(WKBundleRef, WKBundlePageRef);
 
70
    virtual void willDestroyPage(WKBundleRef, WKBundlePageRef);
 
71
    
 
72
    void globalObjectIsAvailableForFrame(WKBundleFrameRef, WKBundleScriptWorldRef);
 
73
    void willDisconnectDOMWindowExtensionFromGlobalObject(WKBundleDOMWindowExtensionRef);
 
74
    void didReconnectDOMWindowExtensionToGlobalObject(WKBundleDOMWindowExtensionRef);
 
75
    void willDestroyGlobalObjectForDOMWindowExtension(WKBundleDOMWindowExtensionRef);
 
76
 
 
77
    void frameLoadFinished(WKBundleFrameRef);
 
78
 
 
79
private:
 
80
    void updateExtensionStateRecord(WKBundleDOMWindowExtensionRef, ExtensionState);
 
81
    void sendExtensionStateMessage();
 
82
    void sendBundleMessage(const char*);
 
83
 
 
84
    WKBundleRef m_bundle;
 
85
    ExtensionRecord m_extensionRecords[6];
 
86
    HashMap<WKBundleDOMWindowExtensionRef, int> m_extensionToRecordMap;
 
87
    bool m_finishedOneMainFrameLoad;
 
88
};
 
89
 
 
90
static InjectedBundleTest::Register<DOMWindowExtensionBasic> registrar("DOMWindowExtensionBasic");
 
91
 
 
92
DOMWindowExtensionBasic::DOMWindowExtensionBasic(const std::string& identifier)
 
93
    : InjectedBundleTest(identifier)
 
94
    , m_finishedOneMainFrameLoad(false)
 
95
{
 
96
    m_extensionRecords[0].name = "First page, main frame, standard world";
 
97
    m_extensionRecords[1].name = "First page, main frame, non-standard world";
 
98
    m_extensionRecords[2].name = "First page, subframe, standard world";
 
99
    m_extensionRecords[3].name = "First page, subframe, non-standard world";
 
100
    m_extensionRecords[4].name = "Second page, main frame, standard world";
 
101
    m_extensionRecords[5].name = "Second page, main frame, non-standard world";
 
102
    
 
103
    for (size_t i = 0; i < 6; ++i)
 
104
        m_extensionRecords[i].state = Uncreated;
 
105
}
 
106
 
 
107
void DOMWindowExtensionBasic::frameLoadFinished(WKBundleFrameRef frame)
 
108
{
 
109
    bool mainFrame = !WKBundleFrameGetParentFrame(frame);
 
110
    if (mainFrame)
 
111
        m_finishedOneMainFrameLoad = true;
 
112
 
 
113
    char body[16384];
 
114
    sprintf(body, "%s finished loading", mainFrame ? "Main frame" : "Subframe");
 
115
    
 
116
    // Only consider load finished for the main frame
 
117
    const char* name = mainFrame ? "DidFinishLoadForMainFrame" : "DidFinishLoadForFrame";
 
118
 
 
119
    WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString(name));
 
120
    WKRetainPtr<WKStringRef> messageBody = adoptWK(WKStringCreateWithUTF8CString(body));
 
121
    WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
 
122
    
 
123
    sendExtensionStateMessage();
 
124
}
 
125
 
 
126
void DOMWindowExtensionBasic::sendExtensionStateMessage()
 
127
{
 
128
    char body[16384];
 
129
    sprintf(body, "Extension states:\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s",
 
130
        m_extensionRecords[0].name, stateNames[m_extensionRecords[0].state],
 
131
        m_extensionRecords[1].name, stateNames[m_extensionRecords[1].state],
 
132
        m_extensionRecords[2].name, stateNames[m_extensionRecords[2].state],
 
133
        m_extensionRecords[3].name, stateNames[m_extensionRecords[3].state],
 
134
        m_extensionRecords[4].name, stateNames[m_extensionRecords[4].state],
 
135
        m_extensionRecords[5].name, stateNames[m_extensionRecords[5].state]);
 
136
 
 
137
    WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("ExtensionStates"));
 
138
    WKRetainPtr<WKStringRef> messageBody = adoptWK(WKStringCreateWithUTF8CString(body));
 
139
    WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
 
140
}
 
141
 
 
142
void DOMWindowExtensionBasic::initialize(WKBundleRef bundle, WKTypeRef userData)
 
143
{
 
144
    assert(WKGetTypeID(userData) == WKBundlePageGroupGetTypeID());
 
145
    WKBundlePageGroupRef pageGroup = static_cast<WKBundlePageGroupRef>(userData);
 
146
 
 
147
    WKRetainPtr<WKStringRef> source(AdoptWK, WKStringCreateWithUTF8CString("alert('Unimportant alert');"));
 
148
    WKBundleAddUserScript(bundle, pageGroup, WKBundleScriptWorldCreateWorld(), source.get(), 0, 0, 0, kWKInjectAtDocumentStart, kWKInjectInAllFrames);
 
149
}
 
150
 
 
151
void DOMWindowExtensionBasic::didCreatePage(WKBundleRef bundle, WKBundlePageRef page)
 
152
{    
 
153
    m_bundle = bundle;
 
154
 
 
155
    WKBundlePageLoaderClient pageLoaderClient;
 
156
    memset(&pageLoaderClient, 0, sizeof(pageLoaderClient));
 
157
    
 
158
    pageLoaderClient.version = 1;
 
159
    pageLoaderClient.clientInfo = this;
 
160
    pageLoaderClient.didFinishLoadForFrame = didFinishLoadForFrameCallback;
 
161
    pageLoaderClient.globalObjectIsAvailableForFrame = globalObjectIsAvailableForFrameCallback;
 
162
    pageLoaderClient.willDisconnectDOMWindowExtensionFromGlobalObject = willDisconnectDOMWindowExtensionFromGlobalObjectCallback;
 
163
    pageLoaderClient.didReconnectDOMWindowExtensionToGlobalObject = didReconnectDOMWindowExtensionToGlobalObjectCallback;
 
164
    pageLoaderClient.willDestroyGlobalObjectForDOMWindowExtension = willDestroyGlobalObjectForDOMWindowExtensionCallback;
 
165
    
 
166
    WKBundlePageSetPageLoaderClient(page, &pageLoaderClient);
 
167
}
 
168
 
 
169
void DOMWindowExtensionBasic::willDestroyPage(WKBundleRef, WKBundlePageRef)
 
170
{
 
171
    HashMap<WKBundleDOMWindowExtensionRef, int>::iterator it = m_extensionToRecordMap.begin();
 
172
    HashMap<WKBundleDOMWindowExtensionRef, int>::iterator end = m_extensionToRecordMap.end();
 
173
    for (; it != end; ++it) {
 
174
        updateExtensionStateRecord(it->key, Removed);
 
175
        WKRelease(it->key);
 
176
    }
 
177
 
 
178
    m_extensionToRecordMap.clear();
 
179
 
 
180
    sendExtensionStateMessage();
 
181
    sendBundleMessage("TestComplete");
 
182
}
 
183
    
 
184
void DOMWindowExtensionBasic::updateExtensionStateRecord(WKBundleDOMWindowExtensionRef extension, ExtensionState state)
 
185
{
 
186
    int index = m_extensionToRecordMap.get(extension);
 
187
    m_extensionRecords[index].state = state;
 
188
}
 
189
 
 
190
void DOMWindowExtensionBasic::sendBundleMessage(const char* message)
 
191
{
 
192
    WKRetainPtr<WKStringRef> wkMessage = adoptWK(WKStringCreateWithUTF8CString(message));
 
193
    WKBundlePostMessage(m_bundle, wkMessage.get(), wkMessage.get());
 
194
}
 
195
 
 
196
void DOMWindowExtensionBasic::globalObjectIsAvailableForFrame(WKBundleFrameRef frame, WKBundleScriptWorldRef world)
 
197
{
 
198
    WKBundleDOMWindowExtensionRef extension = WKBundleDOMWindowExtensionCreate(frame, world);
 
199
 
 
200
    int index;
 
201
    bool standard;
 
202
    standard = world == WKBundleScriptWorldNormalWorld();
 
203
 
 
204
    if (WKBundleFrameGetParentFrame(frame))
 
205
        index = standard ? 2 : 3;
 
206
    else
 
207
        index = m_finishedOneMainFrameLoad ? (standard ? 4 : 5) : (standard ? 0 : 1);
 
208
 
 
209
    m_extensionToRecordMap.set(extension, index);
 
210
 
 
211
    updateExtensionStateRecord(extension, Connected);
 
212
    sendBundleMessage("GlobalObjectIsAvailableForFrame called");
 
213
}
 
214
 
 
215
void DOMWindowExtensionBasic::willDisconnectDOMWindowExtensionFromGlobalObject(WKBundleDOMWindowExtensionRef extension)
 
216
{
 
217
    updateExtensionStateRecord(extension, Disconnected);
 
218
    sendBundleMessage("WillDisconnectDOMWindowExtensionFromGlobalObject called");
 
219
}
 
220
 
 
221
void DOMWindowExtensionBasic::didReconnectDOMWindowExtensionToGlobalObject(WKBundleDOMWindowExtensionRef extension)
 
222
{
 
223
    updateExtensionStateRecord(extension, Connected);
 
224
    sendBundleMessage("DidReconnectDOMWindowExtensionToGlobalObject called");
 
225
}
 
226
 
 
227
void DOMWindowExtensionBasic::willDestroyGlobalObjectForDOMWindowExtension(WKBundleDOMWindowExtensionRef)
 
228
{
 
229
    // All of the items are candidates for the page cache and should not be evicted from the page
 
230
    // cache before the test completes.
 
231
    ASSERT_NOT_REACHED();
 
232
}
 
233
 
 
234
static void didFinishLoadForFrameCallback(WKBundlePageRef, WKBundleFrameRef frame, WKTypeRef*, const void *clientInfo)
 
235
{
 
236
    ((DOMWindowExtensionBasic*)clientInfo)->frameLoadFinished(frame);
 
237
}
 
238
 
 
239
static void globalObjectIsAvailableForFrameCallback(WKBundlePageRef, WKBundleFrameRef frame, WKBundleScriptWorldRef world, const void* clientInfo)
 
240
{
 
241
    ((DOMWindowExtensionBasic*)clientInfo)->globalObjectIsAvailableForFrame(frame, world);
 
242
}
 
243
 
 
244
static void willDisconnectDOMWindowExtensionFromGlobalObjectCallback(WKBundlePageRef, WKBundleDOMWindowExtensionRef extension, const void* clientInfo)
 
245
{
 
246
    ((DOMWindowExtensionBasic*)clientInfo)->willDisconnectDOMWindowExtensionFromGlobalObject(extension);
 
247
}
 
248
 
 
249
static void didReconnectDOMWindowExtensionToGlobalObjectCallback(WKBundlePageRef, WKBundleDOMWindowExtensionRef extension, const void* clientInfo)
 
250
{
 
251
    ((DOMWindowExtensionBasic*)clientInfo)->didReconnectDOMWindowExtensionToGlobalObject(extension);
 
252
}
 
253
 
 
254
static void willDestroyGlobalObjectForDOMWindowExtensionCallback(WKBundlePageRef, WKBundleDOMWindowExtensionRef extension , const void* clientInfo)
 
255
{
 
256
    ((DOMWindowExtensionBasic*)clientInfo)->willDestroyGlobalObjectForDOMWindowExtension(extension);
 
257
}
 
258
 
 
259
} // namespace TestWebKitAPI