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.
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.
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.
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.
34 #include "PluginObject.h"
36 #include "TestObject.h"
40 static void pluginInvalidate(NPObject *obj);
41 static bool pluginHasProperty(NPObject *obj, NPIdentifier name);
42 static bool pluginHasMethod(NPObject *obj, NPIdentifier name);
43 static bool pluginGetProperty(NPObject *obj, NPIdentifier name, NPVariant *variant);
44 static bool pluginSetProperty(NPObject *obj, NPIdentifier name, const NPVariant *variant);
45 static bool pluginInvoke(NPObject *obj, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result);
46 static bool pluginInvokeDefault(NPObject *obj, const NPVariant *args, uint32_t argCount, NPVariant *result);
47 static NPObject *pluginAllocate(NPP npp, NPClass *theClass);
48 static void pluginDeallocate(NPObject *obj);
50 NPNetscapeFuncs *browser;
52 static NPClass pluginClass = {
53 NP_CLASS_STRUCT_VERSION,
65 NPClass *getPluginClass(void)
70 static bool identifiersInitialized = false;
72 #define ID_PROPERTY_PROPERTY 0
73 #define ID_PROPERTY_EVENT_LOGGING 1
74 #define ID_PROPERTY_HAS_STREAM 2
75 #define ID_PROPERTY_TEST_OBJECT 3
76 #define ID_PROPERTY_LOG_DESTROY 4
77 #define NUM_PROPERTY_IDENTIFIERS 5
79 static NPIdentifier pluginPropertyIdentifiers[NUM_PROPERTY_IDENTIFIERS];
80 static const NPUTF8 *pluginPropertyIdentifierNames[NUM_PROPERTY_IDENTIFIERS] = {
82 "eventLoggingEnabled",
88 #define ID_TEST_CALLBACK_METHOD 0
89 #define ID_TEST_GETURL 1
90 #define ID_REMOVE_DEFAULT_METHOD 2
91 #define ID_TEST_DOM_ACCESS 3
92 #define ID_TEST_GET_URL_NOTIFY 4
93 #define ID_TEST_INVOKE_DEFAULT 5
94 #define ID_DESTROY_STREAM 6
95 #define ID_TEST_ENUMERATE 7
96 #define ID_TEST_GETINTIDENTIFIER 8
97 #define ID_TEST_GET_PROPERTY 9
98 #define ID_TEST_EVALUATE 10
99 #define NUM_METHOD_IDENTIFIERS 11
101 static NPIdentifier pluginMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
102 static const NPUTF8 *pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
105 "removeDefaultMethod",
111 "testGetIntIdentifier",
116 static NPUTF8* createCStringFromNPVariant(const NPVariant *variant)
118 size_t length = NPVARIANT_TO_STRING(*variant).UTF8Length;
119 NPUTF8* result = (NPUTF8*)malloc(length + 1);
120 memcpy(result, NPVARIANT_TO_STRING(*variant).UTF8Characters, length);
121 result[length] = '\0';
125 static void initializeIdentifiers(void)
127 browser->getstringidentifiers(pluginPropertyIdentifierNames, NUM_PROPERTY_IDENTIFIERS, pluginPropertyIdentifiers);
128 browser->getstringidentifiers(pluginMethodIdentifierNames, NUM_METHOD_IDENTIFIERS, pluginMethodIdentifiers);
131 static bool pluginHasProperty(NPObject *obj, NPIdentifier name)
133 for (int i = 0; i < NUM_PROPERTY_IDENTIFIERS; i++)
134 if (name == pluginPropertyIdentifiers[i])
139 static bool pluginHasMethod(NPObject *obj, NPIdentifier name)
141 for (int i = 0; i < NUM_METHOD_IDENTIFIERS; i++)
142 if (name == pluginMethodIdentifiers[i])
147 static bool pluginGetProperty(NPObject *obj, NPIdentifier name, NPVariant *variant)
149 if (name == pluginPropertyIdentifiers[ID_PROPERTY_PROPERTY]) {
150 STRINGZ_TO_NPVARIANT("property", *variant);
152 } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) {
153 BOOLEAN_TO_NPVARIANT(((PluginObject *)obj)->eventLogging, *variant);
155 } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) {
156 BOOLEAN_TO_NPVARIANT(((PluginObject *)obj)->logDestroy, *variant);
158 } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_HAS_STREAM]) {
159 BOOLEAN_TO_NPVARIANT(((PluginObject *)obj)->stream != 0, *variant);
161 } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_TEST_OBJECT]) {
162 NPObject *testObject = ((PluginObject *)obj)->testObject;
163 browser->retainobject(testObject);
164 OBJECT_TO_NPVARIANT(testObject, *variant);
170 static bool pluginSetProperty(NPObject *obj, NPIdentifier name, const NPVariant *variant)
172 if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) {
173 ((PluginObject *)obj)->eventLogging = NPVARIANT_TO_BOOLEAN(*variant);
175 } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) {
176 ((PluginObject *)obj)->logDestroy = NPVARIANT_TO_BOOLEAN(*variant);
183 static void testDOMAccess(PluginObject *obj)
185 // Get plug-in's DOM element
186 NPObject *elementObject;
187 if (browser->getvalue(obj->npp, NPNVPluginElementNPObject, &elementObject) == NPERR_NO_ERROR) {
189 NPVariant styleVariant;
190 NPIdentifier styleIdentifier = browser->getstringidentifier("style");
191 if (browser->getproperty(obj->npp, elementObject, styleIdentifier, &styleVariant) && NPVARIANT_IS_OBJECT(styleVariant)) {
193 NPIdentifier borderIdentifier = browser->getstringidentifier("border");
194 NPVariant borderVariant;
195 STRINGZ_TO_NPVARIANT("3px solid red", borderVariant);
196 browser->setproperty(obj->npp, NPVARIANT_TO_OBJECT(styleVariant), borderIdentifier, &borderVariant);
197 browser->releasevariantvalue(&styleVariant);
200 browser->releaseobject(elementObject);
204 static bool pluginInvoke(NPObject *header, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result)
206 PluginObject *obj = (PluginObject *)header;
207 if (name == pluginMethodIdentifiers[ID_TEST_CALLBACK_METHOD]) {
208 // call whatever method name we're given
209 if (argCount > 0 && NPVARIANT_IS_STRING(args[0])) {
210 NPObject *windowScriptObject;
211 browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
213 NPUTF8* callbackString = createCStringFromNPVariant(&args[0]);
214 NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString);
215 free(callbackString);
217 NPVariant browserResult;
218 browser->invoke(obj->npp, windowScriptObject, callbackIdentifier, 0, 0, &browserResult);
219 browser->releasevariantvalue(&browserResult);
221 VOID_TO_NPVARIANT(*result);
224 } else if (name == pluginMethodIdentifiers[ID_TEST_GETURL]) {
225 if (argCount == 2 && NPVARIANT_IS_STRING(args[0]) && NPVARIANT_IS_STRING(args[1])) {
226 NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
227 NPUTF8* targetString = createCStringFromNPVariant(&args[1]);
228 browser->geturl(obj->npp, urlString, targetString);
232 VOID_TO_NPVARIANT(*result);
234 } else if (argCount == 1 && NPVARIANT_IS_STRING(args[0])) {
235 NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
236 browser->geturl(obj->npp, urlString, 0);
239 VOID_TO_NPVARIANT(*result);
242 } else if (name == pluginMethodIdentifiers[ID_REMOVE_DEFAULT_METHOD]) {
243 pluginClass.invokeDefault = 0;
244 VOID_TO_NPVARIANT(*result);
246 } else if (name == pluginMethodIdentifiers[ID_TEST_DOM_ACCESS]) {
248 VOID_TO_NPVARIANT(*result);
250 } else if (name == pluginMethodIdentifiers[ID_TEST_GET_URL_NOTIFY]) {
252 && NPVARIANT_IS_STRING(args[0])
253 && (NPVARIANT_IS_STRING(args[1]) || NPVARIANT_IS_NULL(args[1]))
254 && NPVARIANT_IS_STRING(args[2])) {
255 NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
256 NPUTF8* targetString = (NPVARIANT_IS_STRING(args[1]) ? createCStringFromNPVariant(&args[1]) : NULL);
257 NPUTF8* callbackString = createCStringFromNPVariant(&args[2]);
259 NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString);
260 browser->geturlnotify(obj->npp, urlString, targetString, callbackIdentifier);
264 free(callbackString);
266 VOID_TO_NPVARIANT(*result);
269 } else if (name == pluginMethodIdentifiers[ID_TEST_INVOKE_DEFAULT] && NPVARIANT_IS_OBJECT(args[0])) {
270 NPObject *callback = NPVARIANT_TO_OBJECT(args[0]);
273 NPVariant browserResult;
275 STRINGZ_TO_NPVARIANT("test", args[0]);
276 bool retval = browser->invokeDefault(obj->npp, callback, args, 1, &browserResult);
279 browser->releasevariantvalue(&browserResult);
281 BOOLEAN_TO_NPVARIANT(retval, *result);
283 } else if (name == pluginMethodIdentifiers[ID_TEST_ENUMERATE]) {
284 if (argCount == 2 && NPVARIANT_IS_OBJECT(args[0]) && NPVARIANT_IS_OBJECT(args[1])) {
286 NPIdentifier* identifiers;
288 if (browser->enumerate(obj->npp, NPVARIANT_TO_OBJECT(args[0]), &identifiers, &count)) {
289 NPObject* outArray = NPVARIANT_TO_OBJECT(args[1]);
290 NPIdentifier pushIdentifier = browser->getstringidentifier("push");
292 for (uint32_t i = 0; i < count; i++) {
293 NPUTF8* string = browser->utf8fromidentifier(identifiers[i]);
299 STRINGZ_TO_NPVARIANT(string, args[0]);
300 NPVariant browserResult;
301 browser->invoke(obj->npp, outArray, pushIdentifier, args, 1, &browserResult);
302 browser->releasevariantvalue(&browserResult);
303 browser->memfree(string);
306 browser->memfree(identifiers);
309 VOID_TO_NPVARIANT(*result);
312 } else if (name == pluginMethodIdentifiers[ID_DESTROY_STREAM]) {
313 NPError npError = browser->destroystream(obj->npp, obj->stream, NPRES_USER_BREAK);
314 INT32_TO_NPVARIANT(npError, *result);
316 } else if (name == pluginMethodIdentifiers[ID_TEST_GETINTIDENTIFIER]) {
317 if (argCount == 1 && NPVARIANT_IS_DOUBLE(args[0])) {
318 NPIdentifier identifier = browser->getintidentifier((int)NPVARIANT_TO_DOUBLE(args[0]));
319 INT32_TO_NPVARIANT((int32)identifier, *result);
322 } else if (name == pluginMethodIdentifiers[ID_TEST_EVALUATE] &&
323 argCount == 1 && NPVARIANT_IS_STRING(args[0])) {
324 NPObject *windowScriptObject;
325 browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
327 NPString s = NPVARIANT_TO_STRING(args[0]);
329 bool retval = browser->evaluate(obj->npp, windowScriptObject, &s, result);
330 browser->releaseobject(windowScriptObject);
332 } else if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY] &&
335 browser->getvalue(obj->npp, NPNVWindowNPObject, &object);
337 for (uint32_t i = 0; i < argCount; i++) {
338 assert(NPVARIANT_IS_STRING(args[i]));
339 char *propertyString = createCStringFromNPVariant(&args[i]);
340 NPIdentifier propertyIdentifier = browser->getstringidentifier(propertyString);
343 bool retval = browser->getproperty(obj->npp, object, propertyIdentifier, &variant);
344 browser->releaseobject(object);
349 if (i + 1 < argCount) {
350 assert(NPVARIANT_IS_OBJECT(variant));
351 object = NPVARIANT_TO_OBJECT(variant);
358 VOID_TO_NPVARIANT(*result);
365 static bool pluginInvokeDefault(NPObject *obj, const NPVariant *args, uint32_t argCount, NPVariant *result)
367 INT32_TO_NPVARIANT(1, *result);
371 static void pluginInvalidate(NPObject *obj)
375 static NPObject *pluginAllocate(NPP npp, NPClass *theClass)
377 PluginObject *newInstance = (PluginObject*)malloc(sizeof(PluginObject));
379 if (!identifiersInitialized) {
380 identifiersInitialized = true;
381 initializeIdentifiers();
384 newInstance->npp = npp;
385 newInstance->testObject = browser->createobject(npp, getTestClass());
386 newInstance->eventLogging = FALSE;
387 newInstance->logDestroy = FALSE;
388 newInstance->logSetWindow = FALSE;
389 newInstance->returnErrorFromNewStream = FALSE;
390 newInstance->stream = 0;
392 newInstance->firstUrl = NULL;
393 newInstance->firstHeaders = NULL;
394 newInstance->lastUrl = NULL;
395 newInstance->lastHeaders = NULL;
397 return (NPObject *)newInstance;
400 static void pluginDeallocate(NPObject *header)
402 PluginObject* obj = (PluginObject*)header;
404 browser->releaseobject(obj->testObject);
407 free(obj->firstHeaders);
409 free(obj->lastHeaders);
414 void handleCallback(PluginObject* object, const char *url, NPReason reason, void *notifyData)
420 NPObject *windowScriptObject;
421 browser->getvalue(object->npp, NPNVWindowNPObject, &windowScriptObject);
423 NPIdentifier callbackIdentifier = notifyData;
425 INT32_TO_NPVARIANT(reason, args[0]);
428 if (object->firstUrl && object->firstHeaders && object->lastUrl && object->lastHeaders) {
429 // Format expected by JavaScript validator: four fields separated by \n\n:
430 // First URL; first header block; last URL; last header block.
431 // Note that header blocks already end with \n due to how NPStream::headers works.
432 int len = strlen(object->firstUrl) + 2
433 + strlen(object->firstHeaders) + 1
434 + strlen(object->lastUrl) + 2
435 + strlen(object->lastHeaders) + 1;
436 strHdr = (char*)malloc(len + 1);
437 snprintf(strHdr, len + 1, "%s\n\n%s\n%s\n\n%s\n",
438 object->firstUrl, object->firstHeaders, object->lastUrl, object->lastHeaders);
439 STRINGN_TO_NPVARIANT(strHdr, len, args[1]);
441 NULL_TO_NPVARIANT(args[1]);
443 NPVariant browserResult;
444 browser->invoke(object->npp, windowScriptObject, callbackIdentifier, args, 2, &browserResult);
445 browser->releasevariantvalue(&browserResult);
450 void notifyStream(PluginObject* object, const char *url, const char *headers)
452 if (object->firstUrl == NULL) {
454 object->firstUrl = strdup(url);
456 object->firstHeaders = strdup(headers);
458 free(object->lastUrl);
459 free(object->lastHeaders);
460 object->lastUrl = (url ? strdup(url) : NULL);
461 object->lastHeaders = (headers ? strdup(headers) : NULL);