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 NUM_METHOD_IDENTIFIERS 9
99 static NPIdentifier pluginMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
100 static const NPUTF8 *pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
103 "removeDefaultMethod",
109 "testGetIntIdentifier"
112 static NPUTF8* createCStringFromNPVariant(const NPVariant *variant)
114 size_t length = NPVARIANT_TO_STRING(*variant).UTF8Length;
115 NPUTF8* result = (NPUTF8*)malloc(length + 1);
116 memcpy(result, NPVARIANT_TO_STRING(*variant).UTF8Characters, length);
117 result[length] = '\0';
121 static void initializeIdentifiers(void)
123 browser->getstringidentifiers(pluginPropertyIdentifierNames, NUM_PROPERTY_IDENTIFIERS, pluginPropertyIdentifiers);
124 browser->getstringidentifiers(pluginMethodIdentifierNames, NUM_METHOD_IDENTIFIERS, pluginMethodIdentifiers);
127 static bool pluginHasProperty(NPObject *obj, NPIdentifier name)
129 for (int i = 0; i < NUM_PROPERTY_IDENTIFIERS; i++)
130 if (name == pluginPropertyIdentifiers[i])
135 static bool pluginHasMethod(NPObject *obj, NPIdentifier name)
137 for (int i = 0; i < NUM_METHOD_IDENTIFIERS; i++)
138 if (name == pluginMethodIdentifiers[i])
143 static bool pluginGetProperty(NPObject *obj, NPIdentifier name, NPVariant *variant)
145 if (name == pluginPropertyIdentifiers[ID_PROPERTY_PROPERTY]) {
146 STRINGZ_TO_NPVARIANT("property", *variant);
148 } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) {
149 BOOLEAN_TO_NPVARIANT(((PluginObject *)obj)->eventLogging, *variant);
151 } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) {
152 BOOLEAN_TO_NPVARIANT(((PluginObject *)obj)->logDestroy, *variant);
154 } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_HAS_STREAM]) {
155 BOOLEAN_TO_NPVARIANT(((PluginObject *)obj)->stream != 0, *variant);
157 } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_TEST_OBJECT]) {
158 NPObject *testObject = ((PluginObject *)obj)->testObject;
159 browser->retainobject(testObject);
160 OBJECT_TO_NPVARIANT(testObject, *variant);
166 static bool pluginSetProperty(NPObject *obj, NPIdentifier name, const NPVariant *variant)
168 if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) {
169 ((PluginObject *)obj)->eventLogging = NPVARIANT_TO_BOOLEAN(*variant);
171 } else if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) {
172 ((PluginObject *)obj)->logDestroy = NPVARIANT_TO_BOOLEAN(*variant);
179 static void testDOMAccess(PluginObject *obj)
181 // Get plug-in's DOM element
182 NPObject *elementObject;
183 if (browser->getvalue(obj->npp, NPNVPluginElementNPObject, &elementObject) == NPERR_NO_ERROR) {
185 NPVariant styleVariant;
186 NPIdentifier styleIdentifier = browser->getstringidentifier("style");
187 if (browser->getproperty(obj->npp, elementObject, styleIdentifier, &styleVariant) && NPVARIANT_IS_OBJECT(styleVariant)) {
189 NPIdentifier borderIdentifier = browser->getstringidentifier("border");
190 NPVariant borderVariant;
191 STRINGZ_TO_NPVARIANT("3px solid red", borderVariant);
192 browser->setproperty(obj->npp, NPVARIANT_TO_OBJECT(styleVariant), borderIdentifier, &borderVariant);
193 browser->releasevariantvalue(&styleVariant);
196 browser->releaseobject(elementObject);
200 static bool pluginInvoke(NPObject *header, NPIdentifier name, const NPVariant *args, uint32_t argCount, NPVariant *result)
202 PluginObject *obj = (PluginObject *)header;
203 if (name == pluginMethodIdentifiers[ID_TEST_CALLBACK_METHOD]) {
204 // call whatever method name we're given
205 if (argCount > 0 && NPVARIANT_IS_STRING(args[0])) {
206 NPObject *windowScriptObject;
207 browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);
209 NPUTF8* callbackString = createCStringFromNPVariant(&args[0]);
210 NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString);
211 free(callbackString);
213 NPVariant browserResult;
214 browser->invoke(obj->npp, windowScriptObject, callbackIdentifier, 0, 0, &browserResult);
215 browser->releasevariantvalue(&browserResult);
217 VOID_TO_NPVARIANT(*result);
220 } else if (name == pluginMethodIdentifiers[ID_TEST_GETURL]) {
221 if (argCount == 2 && NPVARIANT_IS_STRING(args[0]) && NPVARIANT_IS_STRING(args[1])) {
222 NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
223 NPUTF8* targetString = createCStringFromNPVariant(&args[1]);
224 browser->geturl(obj->npp, urlString, targetString);
228 VOID_TO_NPVARIANT(*result);
230 } else if (argCount == 1 && NPVARIANT_IS_STRING(args[0])) {
231 NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
232 browser->geturl(obj->npp, urlString, 0);
235 VOID_TO_NPVARIANT(*result);
238 } else if (name == pluginMethodIdentifiers[ID_REMOVE_DEFAULT_METHOD]) {
239 pluginClass.invokeDefault = 0;
240 VOID_TO_NPVARIANT(*result);
242 } else if (name == pluginMethodIdentifiers[ID_TEST_DOM_ACCESS]) {
244 VOID_TO_NPVARIANT(*result);
246 } else if (name == pluginMethodIdentifiers[ID_TEST_GET_URL_NOTIFY]) {
248 && NPVARIANT_IS_STRING(args[0])
249 && (NPVARIANT_IS_STRING(args[1]) || NPVARIANT_IS_NULL(args[1]))
250 && NPVARIANT_IS_STRING(args[2])) {
251 NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
252 NPUTF8* targetString = (NPVARIANT_IS_STRING(args[1]) ? createCStringFromNPVariant(&args[1]) : NULL);
253 NPUTF8* callbackString = createCStringFromNPVariant(&args[2]);
255 NPIdentifier callbackIdentifier = browser->getstringidentifier(callbackString);
256 browser->geturlnotify(obj->npp, urlString, targetString, callbackIdentifier);
260 free(callbackString);
262 VOID_TO_NPVARIANT(*result);
265 } else if (name == pluginMethodIdentifiers[ID_TEST_INVOKE_DEFAULT] && NPVARIANT_IS_OBJECT(args[0])) {
266 NPObject *callback = NPVARIANT_TO_OBJECT(args[0]);
269 NPVariant browserResult;
271 STRINGZ_TO_NPVARIANT("test", args[0]);
272 bool retval = browser->invokeDefault(obj->npp, callback, args, 1, &browserResult);
275 browser->releasevariantvalue(&browserResult);
277 BOOLEAN_TO_NPVARIANT(retval, *result);
279 } else if (name == pluginMethodIdentifiers[ID_TEST_ENUMERATE]) {
280 if (argCount == 2 && NPVARIANT_IS_OBJECT(args[0]) && NPVARIANT_IS_OBJECT(args[1])) {
282 NPIdentifier* identifiers;
284 if (browser->enumerate(obj->npp, NPVARIANT_TO_OBJECT(args[0]), &identifiers, &count)) {
285 NPObject* outArray = NPVARIANT_TO_OBJECT(args[1]);
286 NPIdentifier pushIdentifier = browser->getstringidentifier("push");
288 for (uint32_t i = 0; i < count; i++) {
289 NPUTF8* string = browser->utf8fromidentifier(identifiers[i]);
295 STRINGZ_TO_NPVARIANT(string, args[0]);
296 NPVariant browserResult;
297 browser->invoke(obj->npp, outArray, pushIdentifier, args, 1, &browserResult);
298 browser->releasevariantvalue(&browserResult);
299 browser->memfree(string);
302 browser->memfree(identifiers);
305 VOID_TO_NPVARIANT(*result);
308 } else if (name == pluginMethodIdentifiers[ID_DESTROY_STREAM]) {
309 NPError npError = browser->destroystream(obj->npp, obj->stream, NPRES_USER_BREAK);
310 INT32_TO_NPVARIANT(npError, *result);
312 } else if (name == pluginMethodIdentifiers[ID_TEST_GETINTIDENTIFIER]) {
313 if (argCount == 1 && NPVARIANT_IS_DOUBLE(args[0])) {
314 NPIdentifier identifier = browser->getintidentifier((int)NPVARIANT_TO_DOUBLE(args[0]));
315 INT32_TO_NPVARIANT((int32)identifier, *result);
323 static bool pluginInvokeDefault(NPObject *obj, const NPVariant *args, uint32_t argCount, NPVariant *result)
325 INT32_TO_NPVARIANT(1, *result);
329 static void pluginInvalidate(NPObject *obj)
333 static NPObject *pluginAllocate(NPP npp, NPClass *theClass)
335 PluginObject *newInstance = (PluginObject*)malloc(sizeof(PluginObject));
337 if (!identifiersInitialized) {
338 identifiersInitialized = true;
339 initializeIdentifiers();
342 newInstance->npp = npp;
343 newInstance->testObject = browser->createobject(npp, getTestClass());
344 newInstance->eventLogging = FALSE;
345 newInstance->logDestroy = FALSE;
346 newInstance->logSetWindow = FALSE;
347 newInstance->returnErrorFromNewStream = FALSE;
348 newInstance->stream = 0;
350 newInstance->firstUrl = NULL;
351 newInstance->firstHeaders = NULL;
352 newInstance->lastUrl = NULL;
353 newInstance->lastHeaders = NULL;
355 return (NPObject *)newInstance;
358 static void pluginDeallocate(NPObject *header)
360 PluginObject* obj = (PluginObject*)header;
362 browser->releaseobject(obj->testObject);
365 free(obj->firstHeaders);
367 free(obj->lastHeaders);
372 void handleCallback(PluginObject* object, const char *url, NPReason reason, void *notifyData)
378 NPObject *windowScriptObject;
379 browser->getvalue(object->npp, NPNVWindowNPObject, &windowScriptObject);
381 NPIdentifier callbackIdentifier = notifyData;
383 INT32_TO_NPVARIANT(reason, args[0]);
386 if (object->firstUrl && object->firstHeaders && object->lastUrl && object->lastHeaders) {
387 // Format expected by JavaScript validator: four fields separated by \n\n:
388 // First URL; first header block; last URL; last header block.
389 // Note that header blocks already end with \n due to how NPStream::headers works.
390 int len = strlen(object->firstUrl) + 2
391 + strlen(object->firstHeaders) + 1
392 + strlen(object->lastUrl) + 2
393 + strlen(object->lastHeaders) + 1;
394 strHdr = (char*)malloc(len + 1);
395 snprintf(strHdr, len + 1, "%s\n\n%s\n%s\n\n%s\n",
396 object->firstUrl, object->firstHeaders, object->lastUrl, object->lastHeaders);
397 STRINGN_TO_NPVARIANT(strHdr, len, args[1]);
399 NULL_TO_NPVARIANT(args[1]);
401 NPVariant browserResult;
402 browser->invoke(object->npp, windowScriptObject, callbackIdentifier, args, 2, &browserResult);
403 browser->releasevariantvalue(&browserResult);
408 void notifyStream(PluginObject* object, const char *url, const char *headers)
410 if (object->firstUrl == NULL) {
412 object->firstUrl = strdup(url);
414 object->firstHeaders = strdup(headers);
416 free(object->lastUrl);
417 free(object->lastHeaders);
418 object->lastUrl = (url ? strdup(url) : NULL);
419 object->lastHeaders = (headers ? strdup(headers) : NULL);