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

« back to all changes in this revision

Viewing changes to Tools/TestWebKitAPI/Tests/WebKit2/DOMWindowExtensionNoCache_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
enum ExtensionState {
 
47
    Uncreated = 0, Connected, Disconnected, Destroyed, Removed
 
48
};
 
49
 
 
50
const char* states[5] = {
 
51
    "Uncreated",
 
52
    "Connected",
 
53
    "Disconnected",
 
54
    "Destroyed",
 
55
    "Removed"
 
56
};
 
57
 
 
58
typedef struct {
 
59
    const char* name;
 
60
    ExtensionState state;
 
61
} ExtensionRecord;
 
62
 
 
63
class DOMWindowExtensionNoCache : public InjectedBundleTest {
 
64
public:
 
65
    DOMWindowExtensionNoCache(const std::string& identifier);
 
66
 
 
67
    virtual void initialize(WKBundleRef, WKTypeRef userData);
 
68
    virtual void didCreatePage(WKBundleRef, WKBundlePageRef);
 
69
    virtual void willDestroyPage(WKBundleRef, WKBundlePageRef);
 
70
 
 
71
    void globalObjectIsAvailableForFrame(WKBundleFrameRef, WKBundleScriptWorldRef);
 
72
    void willDisconnectDOMWindowExtensionFromGlobalObject(WKBundleDOMWindowExtensionRef);
 
73
    void didReconnectDOMWindowExtensionToGlobalObject(WKBundleDOMWindowExtensionRef);
 
74
    void willDestroyGlobalObjectForDOMWindowExtension(WKBundleDOMWindowExtensionRef);
 
75
 
 
76
    void frameLoadFinished(WKBundleFrameRef);
 
77
 
 
78
private:
 
79
    void updateExtensionStateRecord(WKBundleDOMWindowExtensionRef, ExtensionState);
 
80
    void sendExtensionStateMessage();
 
81
    void sendBundleMessage(const char*);
 
82
 
 
83
    WKBundleRef m_bundle;
 
84
    ExtensionRecord m_extensionRecords[10];
 
85
    HashMap<WKBundleDOMWindowExtensionRef, int> m_extensionToRecordMap;
 
86
    int m_numberMainFrameLoads;
 
87
};
 
88
 
 
89
static InjectedBundleTest::Register<DOMWindowExtensionNoCache> registrar("DOMWindowExtensionNoCache");
 
90
 
 
91
DOMWindowExtensionNoCache::DOMWindowExtensionNoCache(const std::string& identifier)
 
92
    : InjectedBundleTest(identifier)
 
93
    , m_numberMainFrameLoads(0)
 
94
{
 
95
    m_extensionRecords[0].name = "First page, main frame, standard world";
 
96
    m_extensionRecords[1].name = "First page, main frame, non-standard world";
 
97
    m_extensionRecords[2].name = "First page, subframe, standard world";
 
98
    m_extensionRecords[3].name = "First page, subframe, non-standard world";
 
99
    m_extensionRecords[4].name = "Second page, main frame, standard world";
 
100
    m_extensionRecords[5].name = "Second page, main frame, non-standard world";
 
101
    m_extensionRecords[6].name = "First page, main frame, standard world";
 
102
    m_extensionRecords[7].name = "First page, main frame, non-standard world";
 
103
    m_extensionRecords[8].name = "First page, subframe, standard world";
 
104
    m_extensionRecords[9].name = "First page, subframe, non-standard world";
 
105
 
 
106
    for (size_t i = 0; i < 10; ++i)
 
107
      m_extensionRecords[i].state = Uncreated;
 
108
}
 
109
 
 
110
void DOMWindowExtensionNoCache::frameLoadFinished(WKBundleFrameRef frame)
 
111
{
 
112
    bool mainFrame = !WKBundleFrameGetParentFrame(frame);
 
113
    if (mainFrame)
 
114
        m_numberMainFrameLoads++;
 
115
 
 
116
    char body[16384];
 
117
    sprintf(body, "%s finished loading", mainFrame ? "Main frame" : "Subframe");
 
118
 
 
119
    // Only consider load finished for the main frame
 
120
    const char* name = mainFrame ? "DidFinishLoadForMainFrame" : "DidFinishLoadForFrame";
 
121
 
 
122
    WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString(name));
 
123
    WKRetainPtr<WKStringRef> messageBody = adoptWK(WKStringCreateWithUTF8CString(body));
 
124
    WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
 
125
 
 
126
    sendExtensionStateMessage();
 
127
}
 
128
 
 
129
void DOMWindowExtensionNoCache::sendExtensionStateMessage()
 
130
{
 
131
    char body[16384];
 
132
    sprintf(body, "Extension states:\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s\n%s - %s",
 
133
            m_extensionRecords[0].name, states[m_extensionRecords[0].state],
 
134
            m_extensionRecords[1].name, states[m_extensionRecords[1].state],
 
135
            m_extensionRecords[2].name, states[m_extensionRecords[2].state],
 
136
            m_extensionRecords[3].name, states[m_extensionRecords[3].state],
 
137
            m_extensionRecords[4].name, states[m_extensionRecords[4].state],
 
138
            m_extensionRecords[5].name, states[m_extensionRecords[5].state],
 
139
            m_extensionRecords[6].name, states[m_extensionRecords[6].state],
 
140
            m_extensionRecords[7].name, states[m_extensionRecords[7].state],
 
141
            m_extensionRecords[8].name, states[m_extensionRecords[8].state],
 
142
            m_extensionRecords[9].name, states[m_extensionRecords[9].state]);
 
143
 
 
144
    WKRetainPtr<WKStringRef> messageName = adoptWK(WKStringCreateWithUTF8CString("ExtensionStates"));
 
145
    WKRetainPtr<WKStringRef> messageBody = adoptWK(WKStringCreateWithUTF8CString(body));
 
146
    WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
 
147
}
 
148
 
 
149
void DOMWindowExtensionNoCache::initialize(WKBundleRef bundle, WKTypeRef userData)
 
150
{
 
151
    assert(WKGetTypeID(userData) == WKBundlePageGroupGetTypeID());
 
152
    WKBundlePageGroupRef pageGroup = static_cast<WKBundlePageGroupRef>(userData);
 
153
 
 
154
    WKRetainPtr<WKStringRef> source(AdoptWK, WKStringCreateWithUTF8CString("alert('Unimportant alert');"));
 
155
    WKBundleAddUserScript(bundle, pageGroup, WKBundleScriptWorldCreateWorld(), source.get(), 0, 0, 0, kWKInjectAtDocumentStart, kWKInjectInAllFrames);
 
156
}
 
157
 
 
158
void DOMWindowExtensionNoCache::didCreatePage(WKBundleRef bundle, WKBundlePageRef page)
 
159
{
 
160
    m_bundle = bundle;
 
161
 
 
162
    WKBundlePageLoaderClient pageLoaderClient;
 
163
    memset(&pageLoaderClient, 0, sizeof(pageLoaderClient));
 
164
 
 
165
    pageLoaderClient.version = kWKBundlePageLoaderClientCurrentVersion;
 
166
    pageLoaderClient.clientInfo = this;
 
167
    pageLoaderClient.didFinishLoadForFrame = didFinishLoadForFrameCallback;
 
168
    pageLoaderClient.globalObjectIsAvailableForFrame = globalObjectIsAvailableForFrameCallback;
 
169
    pageLoaderClient.willDisconnectDOMWindowExtensionFromGlobalObject = willDisconnectDOMWindowExtensionFromGlobalObjectCallback;
 
170
    pageLoaderClient.didReconnectDOMWindowExtensionToGlobalObject = didReconnectDOMWindowExtensionToGlobalObjectCallback;
 
171
    pageLoaderClient.willDestroyGlobalObjectForDOMWindowExtension = willDestroyGlobalObjectForDOMWindowExtensionCallback;
 
172
 
 
173
    WKBundlePageSetPageLoaderClient(page, &pageLoaderClient);
 
174
}
 
175
 
 
176
void DOMWindowExtensionNoCache::willDestroyPage(WKBundleRef, WKBundlePageRef)
 
177
{
 
178
    HashMap<WKBundleDOMWindowExtensionRef, int>::iterator it = m_extensionToRecordMap.begin();
 
179
    HashMap<WKBundleDOMWindowExtensionRef, int>::iterator end = m_extensionToRecordMap.end();
 
180
    for (; it != end; ++it) {
 
181
        updateExtensionStateRecord(it->key, Removed);
 
182
        WKRelease(it->key);
 
183
    }
 
184
 
 
185
    m_extensionToRecordMap.clear();
 
186
 
 
187
    sendExtensionStateMessage();
 
188
    sendBundleMessage("TestComplete");
 
189
}
 
190
 
 
191
void DOMWindowExtensionNoCache::updateExtensionStateRecord(WKBundleDOMWindowExtensionRef extension, ExtensionState state)
 
192
{
 
193
    int index = m_extensionToRecordMap.get(extension);
 
194
    m_extensionRecords[index].state = state;
 
195
}
 
196
 
 
197
void DOMWindowExtensionNoCache::sendBundleMessage(const char* message)
 
198
{
 
199
    WKRetainPtr<WKStringRef> wkMessage = adoptWK(WKStringCreateWithUTF8CString(message));
 
200
    WKBundlePostMessage(m_bundle, wkMessage.get(), wkMessage.get());
 
201
}
 
202
 
 
203
void DOMWindowExtensionNoCache::globalObjectIsAvailableForFrame(WKBundleFrameRef frame, WKBundleScriptWorldRef world)
 
204
{
 
205
    WKBundleDOMWindowExtensionRef extension = WKBundleDOMWindowExtensionCreate(frame, world);
 
206
 
 
207
    int index;
 
208
    bool standard;
 
209
    standard = world == WKBundleScriptWorldNormalWorld();
 
210
 
 
211
    bool mainFrame = !WKBundleFrameGetParentFrame(frame);
 
212
    switch (m_numberMainFrameLoads) {
 
213
    case 0:
 
214
        index = mainFrame ? (standard ? 0 : 1) : (standard ? 2 : 3);
 
215
        break;
 
216
    case 1:
 
217
        index = standard ? 4 : 5;
 
218
        break;
 
219
    case 2:
 
220
        index = mainFrame ? (standard ? 6 : 7) : (standard ? 8 : 9);
 
221
        break;
 
222
    default:
 
223
        ASSERT_NOT_REACHED();
 
224
        break;
 
225
    }
 
226
 
 
227
    m_extensionToRecordMap.set(extension, index);
 
228
 
 
229
    updateExtensionStateRecord(extension, Connected);
 
230
    sendBundleMessage("GlobalObjectIsAvailableForFrame called");
 
231
}
 
232
 
 
233
void DOMWindowExtensionNoCache::willDisconnectDOMWindowExtensionFromGlobalObject(WKBundleDOMWindowExtensionRef extension)
 
234
{
 
235
    // No items should be going into a 0-capacity page cache.
 
236
    ASSERT_NOT_REACHED();
 
237
}
 
238
 
 
239
void DOMWindowExtensionNoCache::didReconnectDOMWindowExtensionToGlobalObject(WKBundleDOMWindowExtensionRef)
 
240
{
 
241
    // No items should be coming out of a 0-capacity page cache.
 
242
    ASSERT_NOT_REACHED();
 
243
}
 
244
 
 
245
void DOMWindowExtensionNoCache::willDestroyGlobalObjectForDOMWindowExtension(WKBundleDOMWindowExtensionRef extension)
 
246
{
 
247
    sendBundleMessage("WillDestroyDOMWindowExtensionToGlobalObject called");
 
248
    updateExtensionStateRecord(extension, Destroyed);
 
249
    m_extensionToRecordMap.remove(extension);
 
250
    WKRelease(extension);
 
251
}
 
252
 
 
253
static void didFinishLoadForFrameCallback(WKBundlePageRef, WKBundleFrameRef frame, WKTypeRef*, const void *clientInfo)
 
254
{
 
255
    ((DOMWindowExtensionNoCache*)clientInfo)->frameLoadFinished(frame);
 
256
}
 
257
 
 
258
static void globalObjectIsAvailableForFrameCallback(WKBundlePageRef, WKBundleFrameRef frame, WKBundleScriptWorldRef world, const void* clientInfo)
 
259
{
 
260
    ((DOMWindowExtensionNoCache*)clientInfo)->globalObjectIsAvailableForFrame(frame, world);
 
261
}
 
262
 
 
263
static void willDisconnectDOMWindowExtensionFromGlobalObjectCallback(WKBundlePageRef, WKBundleDOMWindowExtensionRef extension, const void* clientInfo)
 
264
{
 
265
    ((DOMWindowExtensionNoCache*)clientInfo)->willDisconnectDOMWindowExtensionFromGlobalObject(extension);
 
266
}
 
267
 
 
268
static void didReconnectDOMWindowExtensionToGlobalObjectCallback(WKBundlePageRef, WKBundleDOMWindowExtensionRef extension, const void* clientInfo)
 
269
{
 
270
    ((DOMWindowExtensionNoCache*)clientInfo)->didReconnectDOMWindowExtensionToGlobalObject(extension);
 
271
}
 
272
 
 
273
static void willDestroyGlobalObjectForDOMWindowExtensionCallback(WKBundlePageRef, WKBundleDOMWindowExtensionRef extension , const void* clientInfo)
 
274
{
 
275
    ((DOMWindowExtensionNoCache*)clientInfo)->willDestroyGlobalObjectForDOMWindowExtension(extension);
 
276
}
 
277
 
 
278
} // namespace TestWebKitAPI