Introduce new SPI for context menus on iOS
[WebKit-https.git] / Source / WebKit / Shared / Cocoa / APIObject.mm
1 /*
2  * Copyright (C) 2013 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 #import "config.h"
27 #import "APIObject.h"
28
29 #import "WKBackForwardListInternal.h"
30 #import "WKBackForwardListItemInternal.h"
31 #import "WKBrowsingContextControllerInternal.h"
32 #import "WKBrowsingContextGroupInternal.h"
33 #import "WKConnectionInternal.h"
34 #import "WKContentRuleListInternal.h"
35 #import "WKContentRuleListStoreInternal.h"
36 #import "WKContextMenuElementInfoInternal.h"
37 #import "WKFrameInfoInternal.h"
38 #import "WKHTTPCookieStoreInternal.h"
39 #import "WKNSArray.h"
40 #import "WKNSData.h"
41 #import "WKNSDictionary.h"
42 #import "WKNSError.h"
43 #import "WKNSNumber.h"
44 #import "WKNSString.h"
45 #import "WKNSURL.h"
46 #import "WKNSURLAuthenticationChallenge.h"
47 #import "WKNSURLRequest.h"
48 #import "WKNavigationActionInternal.h"
49 #import "WKNavigationDataInternal.h"
50 #import "WKNavigationInternal.h"
51 #import "WKNavigationResponseInternal.h"
52 #import "WKOpenPanelParametersInternal.h"
53 #import "WKPreferencesInternal.h"
54 #import "WKProcessPoolInternal.h"
55 #import "WKSecurityOriginInternal.h"
56 #import "WKURLSchemeTaskInternal.h"
57 #import "WKUserContentControllerInternal.h"
58 #import "WKUserScriptInternal.h"
59 #import "WKWebProcessPlugInBrowserContextControllerInternal.h"
60 #import "WKWebProcessPlugInFrameInternal.h"
61 #import "WKWebProcessPlugInHitTestResultInternal.h"
62 #import "WKWebProcessPlugInInternal.h"
63 #import "WKWebProcessPlugInNodeHandleInternal.h"
64 #import "WKWebProcessPlugInPageGroupInternal.h"
65 #import "WKWebProcessPlugInRangeHandleInternal.h"
66 #import "WKWebProcessPlugInScriptWorldInternal.h"
67 #import "WKWebpagePreferencesInternal.h"
68 #import "WKWebsiteDataRecordInternal.h"
69 #import "WKWebsiteDataStoreInternal.h"
70 #import "WKWindowFeaturesInternal.h"
71 #import "_WKAttachmentInternal.h"
72 #import "_WKAutomationSessionInternal.h"
73 #import "_WKContentRuleListActionInternal.h"
74 #import "_WKCustomHeaderFieldsInternal.h"
75 #import "_WKDownloadInternal.h"
76 #import "_WKExperimentalFeatureInternal.h"
77 #import "_WKFrameHandleInternal.h"
78 #import "_WKGeolocationPositionInternal.h"
79 #import "_WKHitTestResultInternal.h"
80 #import "_WKInspectorInternal.h"
81 #import "_WKInternalDebugFeatureInternal.h"
82 #import "_WKProcessPoolConfigurationInternal.h"
83 #import "_WKUserContentWorldInternal.h"
84 #import "_WKUserInitiatedActionInternal.h"
85 #import "_WKUserStyleSheetInternal.h"
86 #import "_WKVisitedLinkStoreInternal.h"
87 #import "_WKWebsiteDataStoreConfigurationInternal.h"
88
89 #if ENABLE(APPLICATION_MANIFEST)
90 #import "_WKApplicationManifestInternal.h"
91 #endif
92
93 static const size_t minimumObjectAlignment = 8;
94 static_assert(minimumObjectAlignment >= alignof(void*), "Objects should always be at least pointer-aligned.");
95 static const size_t maximumExtraSpaceForAlignment = minimumObjectAlignment - alignof(void*);
96
97 namespace API {
98
99 void Object::ref() const
100 {
101     CFRetain((__bridge CFTypeRef)wrapper());
102 }
103
104 void Object::deref() const
105 {
106     CFRelease((__bridge CFTypeRef)wrapper());
107 }
108
109 static id <WKObject> allocateWKObject(Class cls, size_t size)
110 {
111     return class_createInstance(cls, size + maximumExtraSpaceForAlignment);
112 }
113
114 API::Object& Object::fromWKObjectExtraSpace(id <WKObject> obj)
115 {
116     size_t size = sizeof(API::Object);
117     size_t spaceAvailable = size + maximumExtraSpaceForAlignment;
118     void* indexedIvars = object_getIndexedIvars(obj);
119     return *static_cast<API::Object*>(std::align(minimumObjectAlignment, size, indexedIvars, spaceAvailable));
120 }
121
122 void* Object::newObject(size_t size, Type type)
123 {
124     id <WKObject> wrapper;
125
126     // Wrappers that inherit from WKObject store the API::Object in their extra bytes, so they are
127     // allocated using NSAllocatedObject. The other wrapper classes contain inline storage for the
128     // API::Object, so they are allocated using +alloc.
129
130     switch (type) {
131 #if ENABLE(APPLICATION_MANIFEST)
132     case Type::ApplicationManifest:
133         wrapper = [_WKApplicationManifest alloc];
134         break;
135 #endif
136
137     case Type::Array:
138         wrapper = [WKNSArray alloc];
139         break;
140
141 #if ENABLE(ATTACHMENT_ELEMENT)
142     case Type::Attachment:
143         wrapper = [_WKAttachment alloc];
144         break;
145 #endif
146
147     case Type::AuthenticationChallenge:
148         ALLOW_DEPRECATED_DECLARATIONS_BEGIN
149         wrapper = allocateWKObject([WKNSURLAuthenticationChallenge self], size);
150         ALLOW_DEPRECATED_DECLARATIONS_END
151         break;
152
153     case Type::AutomationSession:
154         wrapper = [_WKAutomationSession alloc];
155         break;
156
157     case Type::BackForwardList:
158         wrapper = [WKBackForwardList alloc];
159         break;
160
161     case Type::BackForwardListItem:
162         wrapper = [WKBackForwardListItem alloc];
163         break;
164
165     case Type::Boolean:
166     case Type::Double:
167     case Type::UInt64:
168     case Type::Int64:
169         wrapper = [WKNSNumber alloc];
170         ((WKNSNumber *)wrapper)->_type = type;
171         break;
172
173     case Type::Bundle:
174         wrapper = [WKWebProcessPlugInController alloc];
175         break;
176
177     case Type::BundlePage:
178         wrapper = [WKWebProcessPlugInBrowserContextController alloc];
179         break;
180
181     case Type::Connection:
182         // While not actually a WKObject instance, WKConnection uses allocateWKObject to allocate extra space
183         // instead of using ObjectStorage because the wrapped C++ object is a subclass of WebConnection.
184         ALLOW_DEPRECATED_DECLARATIONS_BEGIN
185         wrapper = allocateWKObject([WKConnection self], size);
186         ALLOW_DEPRECATED_DECLARATIONS_END
187         break;
188
189     case Type::Preferences:
190         wrapper = [WKPreferences alloc];
191         break;
192
193     case Type::ProcessPool:
194         wrapper = [WKProcessPool alloc];
195         break;
196
197     case Type::ProcessPoolConfiguration:
198         wrapper = [_WKProcessPoolConfiguration alloc];
199         break;
200
201     case Type::Data:
202         wrapper = [WKNSData alloc];
203         break;
204
205     case Type::InternalDebugFeature:
206         wrapper = [_WKInternalDebugFeature alloc];
207         break;
208
209     case Type::Dictionary:
210         wrapper = [WKNSDictionary alloc];
211         break;
212
213     case Type::Download:
214         wrapper = [_WKDownload alloc];
215         break;
216
217     case Type::ExperimentalFeature:
218         wrapper = [_WKExperimentalFeature alloc];
219         break;
220
221     case Type::Error:
222         wrapper = allocateWKObject([WKNSError self], size);
223         break;
224
225     case Type::FrameHandle:
226         wrapper = [_WKFrameHandle alloc];
227         break;
228
229     case Type::FrameInfo:
230         wrapper = [WKFrameInfo alloc];
231         break;
232
233 #if PLATFORM(IOS_FAMILY)
234     case Type::GeolocationPosition:
235         wrapper = [_WKGeolocationPosition alloc];
236         break;
237 #endif
238
239     case Type::HTTPCookieStore:
240         wrapper = [WKHTTPCookieStore alloc];
241         break;
242
243 #if PLATFORM(MAC)
244     case Type::HitTestResult:
245         wrapper = [_WKHitTestResult alloc];
246         break;
247 #endif
248
249     case Type::Inspector:
250         wrapper = [_WKInspector alloc];
251         break;
252         
253     case Type::Navigation:
254         wrapper = [WKNavigation alloc];
255         break;
256
257     case Type::NavigationAction:
258         wrapper = [WKNavigationAction alloc];
259         break;
260
261     case Type::NavigationData:
262         wrapper = [WKNavigationData alloc];
263         break;
264
265     case Type::NavigationResponse:
266         wrapper = [WKNavigationResponse alloc];
267         break;
268
269 #if PLATFORM(MAC)
270     case Type::OpenPanelParameters:
271         wrapper = [WKOpenPanelParameters alloc];
272         break;
273 #endif
274
275     case Type::PageGroup:
276         ALLOW_DEPRECATED_DECLARATIONS_BEGIN
277         wrapper = [WKBrowsingContextGroup alloc];
278         ALLOW_DEPRECATED_DECLARATIONS_END
279         break;
280
281     case Type::SecurityOrigin:
282         wrapper = [WKSecurityOrigin alloc];
283         break;
284
285     case Type::String:
286         wrapper = allocateWKObject([WKNSString self], size);
287         break;
288
289     case Type::URL:
290         wrapper = allocateWKObject([WKNSURL self], size);
291         break;
292
293     case Type::URLRequest:
294         wrapper = allocateWKObject([WKNSURLRequest self], size);
295         break;
296
297     case Type::URLSchemeTask:
298         wrapper = [WKURLSchemeTaskImpl alloc];
299         break;
300
301     case Type::UserContentController:
302         wrapper = [WKUserContentController alloc];
303         break;
304
305     case Type::ContentRuleList:
306         wrapper = [WKContentRuleList alloc];
307         break;
308
309     case Type::ContentRuleListAction:
310         wrapper = [_WKContentRuleListAction alloc];
311         break;
312
313     case Type::ContentRuleListStore:
314         wrapper = [WKContentRuleListStore alloc];
315         break;
316
317 #if PLATFORM(IOS_FAMILY)
318     case Type::ContextMenuElementInfo:
319         wrapper = [WKContextMenuElementInfo alloc];
320         break;
321 #endif
322
323     case Type::CustomHeaderFields:
324         wrapper = [_WKCustomHeaderFields alloc];
325         break;
326
327     case Type::UserContentWorld:
328         wrapper = [_WKUserContentWorld alloc];
329         break;
330
331     case Type::UserInitiatedAction:
332         wrapper = [_WKUserInitiatedAction alloc];
333         break;
334
335     case Type::UserScript:
336         wrapper = [WKUserScript alloc];
337         break;
338
339     case Type::UserStyleSheet:
340         wrapper = [_WKUserStyleSheet alloc];
341         break;
342
343     case Type::VisitedLinkStore:
344         wrapper = [_WKVisitedLinkStore alloc];
345         break;
346
347     case Type::WebsiteDataRecord:
348         wrapper = [WKWebsiteDataRecord alloc];
349         break;
350
351     case Type::WebsiteDataStore:
352         wrapper = [WKWebsiteDataStore alloc];
353         break;
354         
355     case Type::WebsiteDataStoreConfiguration:
356         wrapper = [_WKWebsiteDataStoreConfiguration alloc];
357         break;
358
359     case Type::WebsitePolicies:
360         wrapper = [WKWebpagePreferences alloc];
361         break;
362
363     case Type::WindowFeatures:
364         wrapper = [WKWindowFeatures alloc];
365         break;
366
367     case Type::BundleFrame:
368         wrapper = [WKWebProcessPlugInFrame alloc];
369         break;
370
371     case Type::BundleHitTestResult:
372         wrapper = [WKWebProcessPlugInHitTestResult alloc];
373         break;
374
375     case Type::BundleNodeHandle:
376         wrapper = [WKWebProcessPlugInNodeHandle alloc];
377         break;
378
379     case Type::BundlePageGroup:
380         wrapper = [WKWebProcessPlugInPageGroup alloc];
381         break;
382
383     case Type::BundleRangeHandle:
384         wrapper = [WKWebProcessPlugInRangeHandle alloc];
385         break;
386
387     case Type::BundleScriptWorld:
388         wrapper = [WKWebProcessPlugInScriptWorld alloc];
389         break;
390
391     default:
392         wrapper = allocateWKObject([WKObject self], size);
393         break;
394     }
395
396     Object& object = wrapper._apiObject;
397     object.m_wrapper = wrapper;
398
399     return &object;
400 }
401
402 void* Object::wrap(API::Object* object)
403 {
404     if (!object)
405         return nullptr;
406
407     return (__bridge void*)object->wrapper();
408 }
409
410 API::Object* Object::unwrap(void* object)
411 {
412     if (!object)
413         return nullptr;
414
415     return &((__bridge id <WKObject>)object)._apiObject;
416 }
417
418 } // namespace API