LayoutTests:
[WebKit-https.git] / WebKitTools / DumpRenderTree / TestNetscapePlugIn.subproj / PluginObject.c
1 /*
2  IMPORTANT:  This Apple software is supplied to you by Apple Computer, Inc. ("Apple") in
3  consideration of your agreement to the following terms, and your use, installation, 
4  modification or redistribution of this Apple software constitutes acceptance of these 
5  terms.  If you do not agree with these terms, please do not use, install, modify or 
6  redistribute this Apple software.
7  
8  In consideration of your agreement to abide by the following terms, and subject to these 
9  terms, Apple grants you a personal, non-exclusive license, under Appleƕs copyrights in 
10  this original Apple software (the "Apple Software"), to use, reproduce, modify and 
11  redistribute the Apple Software, with or without modifications, in source and/or binary 
12  forms; provided that if you redistribute the Apple Software in its entirety and without 
13  modifications, you must retain this notice and the following text and disclaimers in all 
14  such redistributions of the Apple Software.  Neither the name, trademarks, service marks 
15  or logos of Apple Computer, Inc. may be used to endorse or promote products derived from 
16  the Apple Software without specific prior written permission from Apple. Except as expressly
17  stated in this notice, no other rights or licenses, express or implied, are granted by Apple
18  herein, including but not limited to any patent rights that may be infringed by your 
19  derivative works or by other works in which the Apple Software may be incorporated.
20  
21  The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO WARRANTIES, 
22  EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, 
23  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS 
24  USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
25  
26  IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL 
27  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 
28  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, 
29  REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND 
30  WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR 
31  OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33
34 #import "PluginObject.h"
35
36 static void pluginInvalidate(NPObject *obj);
37 static bool pluginHasProperty(NPObject *obj, NPIdentifier name);
38 static bool pluginHasMethod(NPObject *obj, NPIdentifier name);
39 static bool pluginGetProperty(NPObject *obj, NPIdentifier name, NPVariant *variant);
40 static bool pluginSetProperty(NPObject *obj, NPIdentifier name, const NPVariant *variant);
41 static bool pluginInvoke(NPObject *obj, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result);
42 static bool pluginInvokeDefault(NPObject *obj, const NPVariant *args, uint32_t argCount, NPVariant *result);
43 static NPObject *pluginAllocate(NPP npp, NPClass *theClass);
44 static void pluginDeallocate(NPObject *obj);
45
46 NPNetscapeFuncs *browser;
47
48 static NPClass pluginClass = { 
49     NP_CLASS_STRUCT_VERSION,
50     pluginAllocate, 
51     pluginDeallocate, 
52     pluginInvalidate,
53     pluginHasMethod,
54     pluginInvoke,
55     pluginInvokeDefault,
56     pluginHasProperty,
57     pluginGetProperty,
58     pluginSetProperty,
59 };
60  
61 NPClass *getPluginClass(void)
62 {
63     return &pluginClass;
64 }
65
66 static bool identifiersInitialized = false;
67
68 #define ID_PROPERTY_PROPERTY        0
69 #define ID_PROPERTY_EVENT_LOGGING   1
70 #define ID_PROPERTY_HAS_STREAM      2
71 #define NUM_PROPERTY_IDENTIFIERS    3
72
73 static NPIdentifier pluginPropertyIdentifiers[NUM_PROPERTY_IDENTIFIERS];
74 static const NPUTF8 *pluginPropertyIdentifierNames[NUM_PROPERTY_IDENTIFIERS] = {
75     "property",
76     "eventLoggingEnabled",
77     "hasStream"
78 };
79
80 #define ID_TEST_CALLBACK_METHOD     0
81 #define ID_TEST_GETURL              1
82 #define ID_REMOVE_DEFAULT_METHOD    2
83 #define ID_TEST_DOM_ACCESS          3
84 #define ID_TEST_GET_URL_NOTIFY      4
85 #define ID_TEST_INVOKE_DEFAULT      5
86 #define ID_DESTROY_STREAM           6
87 #define NUM_METHOD_IDENTIFIERS      7
88
89 static NPIdentifier pluginMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
90 static const NPUTF8 *pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
91     "testCallback",
92     "getURL",
93     "removeDefaultMethod",
94     "testDOMAccess",
95     "getURLNotify",
96     "testInvokeDefault",
97     "destroyStream"
98 };
99
100 static NPUTF8* createCStringFromNPVariant(const NPVariant *variant)
101 {
102     size_t length = NPVARIANT_TO_STRING(*variant).UTF8Length;
103     NPUTF8* result = malloc(length + 1);
104     memcpy(result, NPVARIANT_TO_STRING(*variant).UTF8Characters, length);
105     result[length] = '\0';
106     return result;
107 }
108
109 static void initializeIdentifiers(void)
110 {
111     browser->getstringidentifiers(pluginPropertyIdentifierNames, NUM_PROPERTY_IDENTIFIERS, pluginPropertyIdentifiers);
112     browser->getstringidentifiers(pluginMethodIdentifierNames, NUM_METHOD_IDENTIFIERS, pluginMethodIdentifiers);
113 }
114
115 static bool pluginHasProperty(NPObject *obj, NPIdentifier name)
116 {
117     for (int i = 0; i < NUM_PROPERTY_IDENTIFIERS; i++)
118         if (name == pluginPropertyIdentifiers[i])
119             return true;
120     return false;
121 }
122
123 static bool pluginHasMethod(NPObject *obj, NPIdentifier name)
124 {
125     for (int i = 0; i < NUM_METHOD_IDENTIFIERS; i++)
126         if (name == pluginMethodIdentifiers[i])
127             return true;
128     return false;
129 }
130
131 static bool pluginGetProperty(NPObject *obj, NPIdentifier name, NPVariant *variant)
132 {
133     if (name == pluginPropertyIdentifiers[ID_PROPERTY_PROPERTY]) {
134         STRINGZ_TO_NPVARIANT("property", *variant);
135         return true;
136     } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) {
137         BOOLEAN_TO_NPVARIANT(((PluginObject *)obj)->eventLogging, *variant);
138         return true;
139     } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_HAS_STREAM]) {
140         BOOLEAN_TO_NPVARIANT(((PluginObject *)obj)->stream != 0, *variant);
141         return true;
142     }
143     return false;
144 }
145
146 static bool pluginSetProperty(NPObject *obj, NPIdentifier name, const NPVariant *variant)
147 {
148     if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) {
149         ((PluginObject *)obj)->eventLogging = NPVARIANT_TO_BOOLEAN(*variant);
150         return true;
151     }
152     return false;
153 }
154
155 static void testDOMAccess(PluginObject *obj)
156 {
157     // Get plug-in's DOM element
158     NPObject *elementObject;
159     if (browser->getvalue(obj->npp, NPNVPluginElementNPObject, &elementObject) == NPERR_NO_ERROR) {
160         // Get style
161         NPVariant styleVariant;
162         NPIdentifier styleIdentifier = browser->getstringidentifier("style");
163         if (browser->getproperty(obj->npp, elementObject, styleIdentifier, &styleVariant) && NPVARIANT_IS_OBJECT(styleVariant)) {
164             // Set style.border
165             NPIdentifier borderIdentifier = browser->getstringidentifier("border");
166             NPVariant borderVariant;
167             STRINGZ_TO_NPVARIANT("3px solid red", borderVariant);
168             browser->setproperty(obj->npp, NPVARIANT_TO_OBJECT(styleVariant), borderIdentifier, &borderVariant);
169             browser->releasevariantvalue(&styleVariant);
170         }
171         
172         browser->releaseobject(elementObject);
173     }
174 }
175
176 static bool pluginInvoke(NPObject *header, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result)
177 {
178     PluginObject *obj = (PluginObject *)header;
179     if (name == pluginMethodIdentifiers[ID_TEST_CALLBACK_METHOD]) {
180         // call whatever method name we're given
181         if (argCount > 0 && NPVARIANT_IS_STRING(args[0])) {
182             NPObject *windowScriptObject;
183             browser->getvalue(obj->npp, NPPVpluginScriptableNPObject, &windowScriptObject);
184
185             NPUTF8* callbackString = createCStringFromNPVariant(&args[0]);
186             NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString);
187             free(callbackString);
188
189             NPVariant browserResult;
190             browser->invoke(obj->npp, windowScriptObject, callbackIdentifier, 0, 0, &browserResult);
191             browser->releasevariantvalue(&browserResult);
192
193             VOID_TO_NPVARIANT(*result);
194             return true;
195         }
196     } else if (name == pluginMethodIdentifiers[ID_TEST_GETURL]) {
197         if (argCount == 2 && NPVARIANT_IS_STRING(args[0]) && NPVARIANT_IS_STRING(args[1])) {
198             NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
199             NPUTF8* targetString = createCStringFromNPVariant(&args[1]);
200             browser->geturl(obj->npp, urlString, targetString);
201             free(urlString);
202             free(targetString);
203
204             VOID_TO_NPVARIANT(*result);
205             return true;
206         } else if (argCount == 1 && NPVARIANT_IS_STRING(args[0])) {
207             NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
208             browser->geturl(obj->npp, urlString, 0);
209             free(urlString);
210
211             VOID_TO_NPVARIANT(*result);
212             return true;
213         }
214     } else if (name == pluginMethodIdentifiers[ID_REMOVE_DEFAULT_METHOD]) {
215         pluginClass.invokeDefault = 0;
216         VOID_TO_NPVARIANT(*result);
217         return true;
218     } else if (name == pluginMethodIdentifiers[ID_TEST_DOM_ACCESS]) {
219         testDOMAccess(obj);
220         VOID_TO_NPVARIANT(*result);
221         return true;
222     } else if (name == pluginMethodIdentifiers[ID_TEST_GET_URL_NOTIFY]) {
223         if (argCount == 3 && NPVARIANT_IS_STRING(args[0]) && NPVARIANT_IS_STRING(args[1]) && NPVARIANT_IS_STRING(args[2])) {
224             NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
225             NPUTF8* targetString = createCStringFromNPVariant(&args[1]);            
226             NPUTF8* callbackString = createCStringFromNPVariant(&args[2]);
227             
228             NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString);
229             browser->geturlnotify(obj->npp, urlString, targetString, callbackIdentifier);
230
231             free(urlString);
232             free(targetString);
233             free(callbackString);
234             
235             VOID_TO_NPVARIANT(*result);
236             return true;
237         }
238     } else if (name == pluginMethodIdentifiers[ID_TEST_INVOKE_DEFAULT] && NPVARIANT_IS_OBJECT(args[0])) {
239         NPObject *callback = NPVARIANT_TO_OBJECT(args[0]);
240         
241         NPVariant args[1];
242         NPVariant browserResult;
243         
244         STRINGZ_TO_NPVARIANT("test", args[0]);
245         bool retval = browser->invokeDefault(obj->npp, callback, args, 1, &browserResult);
246         
247         if (retval)
248             browser->releasevariantvalue(&browserResult);
249         
250         BOOLEAN_TO_NPVARIANT(retval, *result);
251         return true;        
252     } else if (name == pluginMethodIdentifiers[ID_DESTROY_STREAM]) {
253         assert(obj->stream);
254         NPError npError = browser->destroystream(obj->npp, obj->stream, NPRES_USER_BREAK);
255         INT32_TO_NPVARIANT(npError, *result);
256         return true;        
257     } 
258
259     return false;
260 }
261
262 static bool pluginInvokeDefault(NPObject *obj, const NPVariant *args, uint32_t argCount, NPVariant *result)
263 {
264     INT32_TO_NPVARIANT(1, *result);
265     return true;
266 }
267
268 static void pluginInvalidate(NPObject *obj)
269 {
270 }
271
272 static NPObject *pluginAllocate(NPP npp, NPClass *theClass)
273 {
274     PluginObject *newInstance = malloc(sizeof(PluginObject));
275     
276     if (!identifiersInitialized) {
277         identifiersInitialized = true;
278         initializeIdentifiers();
279     }
280
281     newInstance->npp = npp;
282     newInstance->eventLogging = FALSE;
283     newInstance->stream = 0;
284     
285     return (NPObject *)newInstance;
286 }
287
288 static void pluginDeallocate(NPObject *obj) 
289 {
290     free(obj);
291 }
292
293 void handleCallback(PluginObject* object, const char *url, NPReason reason, void *notifyData)
294 {
295     assert(object);
296     
297     NPVariant args[1];
298     
299     NPObject *windowScriptObject;
300     browser->getvalue(object->npp, NPPVpluginScriptableNPObject, &windowScriptObject);
301     
302     NPIdentifier callbackIdentifier = notifyData;
303
304     INT32_TO_NPVARIANT(reason, args[0]);
305
306     NPVariant browserResult;
307     browser->invoke(object->npp, windowScriptObject, callbackIdentifier, args, 1, &browserResult);
308     browser->releasevariantvalue(&browserResult);
309 }