|
1 /* |
|
2 * Copyright (C) 2010 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 "NetscapeBrowserFuncs.h" |
|
27 |
|
28 #include "NPRuntimeUtilities.h" |
|
29 #include "NetscapePlugin.h" |
|
30 #include "NotImplemented.h" |
|
31 #include <WebCore/HTTPHeaderMap.h> |
|
32 #include <WebCore/IdentifierRep.h> |
|
33 #include <WebCore/SharedBuffer.h> |
|
34 #include <utility> |
|
35 |
|
36 using namespace WebCore; |
|
37 using namespace std; |
|
38 |
|
39 namespace WebKit { |
|
40 |
|
41 static bool startsWithBlankLine(const char* bytes, unsigned length) |
|
42 { |
|
43 return length > 0 && bytes[0] == '\n'; |
|
44 } |
|
45 |
|
46 static int locationAfterFirstBlankLine(const char* bytes, unsigned length) |
|
47 { |
|
48 for (unsigned i = 0; i < length - 4; i++) { |
|
49 // Support for Acrobat. It sends "\n\n". |
|
50 if (bytes[i] == '\n' && bytes[i + 1] == '\n') |
|
51 return i + 2; |
|
52 |
|
53 // Returns the position after 2 CRLF's or 1 CRLF if it is the first line. |
|
54 if (bytes[i] == '\r' && bytes[i + 1] == '\n') { |
|
55 i += 2; |
|
56 if (i == 2) |
|
57 return i; |
|
58 |
|
59 if (bytes[i] == '\n') { |
|
60 // Support for Director. It sends "\r\n\n" (3880387). |
|
61 return i + 1; |
|
62 } |
|
63 |
|
64 if (bytes[i] == '\r' && bytes[i + 1] == '\n') { |
|
65 // Support for Flash. It sends "\r\n\r\n" (3758113). |
|
66 return i + 2; |
|
67 } |
|
68 } |
|
69 } |
|
70 |
|
71 return -1; |
|
72 } |
|
73 |
|
74 static const char* findEndOfLine(const char* bytes, unsigned length) |
|
75 { |
|
76 // According to the HTTP specification EOL is defined as |
|
77 // a CRLF pair. Unfortunately, some servers will use LF |
|
78 // instead. Worse yet, some servers will use a combination |
|
79 // of both (e.g. <header>CRLFLF<body>), so findEOL needs |
|
80 // to be more forgiving. It will now accept CRLF, LF or |
|
81 // CR. |
|
82 // |
|
83 // It returns 0 if EOLF is not found or it will return |
|
84 // a pointer to the first terminating character. |
|
85 for (unsigned i = 0; i < length; i++) { |
|
86 if (bytes[i] == '\n') |
|
87 return bytes + i; |
|
88 if (bytes[i] == '\r') { |
|
89 // Check to see if spanning buffer bounds |
|
90 // (CRLF is across reads). If so, wait for |
|
91 // next read. |
|
92 if (i + 1 == length) |
|
93 break; |
|
94 |
|
95 return bytes + i; |
|
96 } |
|
97 } |
|
98 |
|
99 return 0; |
|
100 } |
|
101 |
|
102 static String capitalizeRFC822HeaderFieldName(const String& name) |
|
103 { |
|
104 bool capitalizeCharacter = true; |
|
105 String result; |
|
106 |
|
107 for (unsigned i = 0; i < name.length(); i++) { |
|
108 UChar c; |
|
109 |
|
110 if (capitalizeCharacter && name[i] >= 'a' && name[i] <= 'z') |
|
111 c = toASCIIUpper(name[i]); |
|
112 else if (!capitalizeCharacter && name[i] >= 'A' && name[i] <= 'Z') |
|
113 c = toASCIILower(name[i]); |
|
114 else |
|
115 c = name[i]; |
|
116 |
|
117 if (name[i] == '-') |
|
118 capitalizeCharacter = true; |
|
119 else |
|
120 capitalizeCharacter = false; |
|
121 |
|
122 result.append(c); |
|
123 } |
|
124 |
|
125 return result; |
|
126 } |
|
127 |
|
128 static HTTPHeaderMap parseRFC822HeaderFields(const char* bytes, unsigned length) |
|
129 { |
|
130 String lastHeaderKey; |
|
131 HTTPHeaderMap headerFields; |
|
132 |
|
133 // Loop over lines until we're past the header, or we can't find any more end-of-lines |
|
134 while (const char* endOfLine = findEndOfLine(bytes, length)) { |
|
135 const char* line = bytes; |
|
136 int lineLength = endOfLine - bytes; |
|
137 |
|
138 // Move bytes to the character after the terminator as returned by findEndOfLine. |
|
139 bytes = endOfLine + 1; |
|
140 if ((*endOfLine == '\r') && (*bytes == '\n')) |
|
141 bytes++; // Safe since findEndOfLine won't return a spanning CRLF. |
|
142 |
|
143 length -= (bytes - line); |
|
144 if (!lineLength) { |
|
145 // Blank line; we're at the end of the header |
|
146 break; |
|
147 } |
|
148 |
|
149 if (*line == ' ' || *line == '\t') { |
|
150 // Continuation of the previous header |
|
151 if (lastHeaderKey.isNull()) { |
|
152 // malformed header; ignore it and continue |
|
153 continue; |
|
154 } |
|
155 |
|
156 // Merge the continuation of the previous header |
|
157 String currentValue = headerFields.get(lastHeaderKey); |
|
158 String newValue(line, lineLength); |
|
159 |
|
160 headerFields.set(lastHeaderKey, currentValue + newValue); |
|
161 } else { |
|
162 // Brand new header |
|
163 const char* colon = line; |
|
164 while (*colon != ':' && colon != endOfLine) |
|
165 colon++; |
|
166 |
|
167 if (colon == endOfLine) { |
|
168 // malformed header; ignore it and continue |
|
169 continue; |
|
170 } |
|
171 |
|
172 lastHeaderKey = capitalizeRFC822HeaderFieldName(String(line, colon - line)); |
|
173 String value; |
|
174 |
|
175 for (colon++; colon != endOfLine; colon++) { |
|
176 if (*colon != ' ' && *colon != '\t') |
|
177 break; |
|
178 } |
|
179 if (colon == endOfLine) |
|
180 value = ""; |
|
181 else |
|
182 value = String(colon, endOfLine - colon); |
|
183 |
|
184 String oldValue = headerFields.get(lastHeaderKey); |
|
185 if (!oldValue.isNull()) { |
|
186 String tmp = oldValue; |
|
187 tmp += ", "; |
|
188 tmp += value; |
|
189 value = tmp; |
|
190 } |
|
191 |
|
192 headerFields.set(lastHeaderKey, value); |
|
193 } |
|
194 } |
|
195 |
|
196 return headerFields; |
|
197 } |
|
198 |
|
199 static NPError parsePostBuffer(bool isFile, const char *buffer, uint32_t length, bool parseHeaders, HTTPHeaderMap& headerFields, Vector<char>& bodyData) |
|
200 { |
|
201 RefPtr<SharedBuffer> fileContents; |
|
202 const char* postBuffer = 0; |
|
203 uint32_t postBufferSize = 0; |
|
204 |
|
205 if (isFile) { |
|
206 fileContents = SharedBuffer::createWithContentsOfFile(String::fromUTF8(buffer)); |
|
207 if (!fileContents) |
|
208 return NPERR_FILE_NOT_FOUND; |
|
209 |
|
210 postBuffer = fileContents->data(); |
|
211 postBufferSize = fileContents->size(); |
|
212 |
|
213 // FIXME: The NPAPI spec states that the file should be deleted here. |
|
214 } else { |
|
215 postBuffer = buffer; |
|
216 postBufferSize = length; |
|
217 } |
|
218 |
|
219 if (parseHeaders) { |
|
220 if (startsWithBlankLine(postBuffer, postBufferSize)) { |
|
221 postBuffer++; |
|
222 postBufferSize--; |
|
223 } else { |
|
224 int location = locationAfterFirstBlankLine(postBuffer, postBufferSize); |
|
225 if (location != -1) { |
|
226 // If the blank line is somewhere in the middle of the buffer, everything before is the header |
|
227 headerFields = parseRFC822HeaderFields(postBuffer, location); |
|
228 unsigned dataLength = postBufferSize - location; |
|
229 |
|
230 // Sometimes plugins like to set Content-Length themselves when they post, |
|
231 // but WebFoundation does not like that. So we will remove the header |
|
232 // and instead truncate the data to the requested length. |
|
233 String contentLength = headerFields.get("Content-Length"); |
|
234 |
|
235 if (!contentLength.isNull()) |
|
236 dataLength = min(contentLength.toInt(), (int)dataLength); |
|
237 headerFields.remove("Content-Length"); |
|
238 |
|
239 postBuffer += location; |
|
240 postBufferSize = dataLength; |
|
241 |
|
242 } |
|
243 } |
|
244 } |
|
245 |
|
246 ASSERT(bodyData.isEmpty()); |
|
247 bodyData.append(postBuffer, postBufferSize); |
|
248 |
|
249 return NPERR_NO_ERROR; |
|
250 } |
|
251 |
|
252 static String makeURLString(const char* url) |
|
253 { |
|
254 String urlString(url); |
|
255 |
|
256 // Strip return characters. |
|
257 urlString.replace('\r', ""); |
|
258 urlString.replace('\n', ""); |
|
259 |
|
260 return urlString; |
|
261 } |
|
262 |
|
263 static NPError NPN_GetURL(NPP npp, const char* url, const char* target) |
|
264 { |
|
265 if (!url) |
|
266 return NPERR_GENERIC_ERROR; |
|
267 |
|
268 RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); |
|
269 plugin->loadURL("GET", makeURLString(url), target, HTTPHeaderMap(), Vector<char>(), false, 0); |
|
270 |
|
271 return NPERR_GENERIC_ERROR; |
|
272 } |
|
273 |
|
274 static NPError NPN_PostURL(NPP npp, const char* url, const char* target, uint32_t len, const char* buf, NPBool file) |
|
275 { |
|
276 HTTPHeaderMap headerFields; |
|
277 Vector<char> postData; |
|
278 |
|
279 // NPN_PostURL only allows headers if the post buffer points to a file. |
|
280 bool parseHeaders = file; |
|
281 |
|
282 NPError error = parsePostBuffer(file, buf, len, parseHeaders, headerFields, postData); |
|
283 if (error != NPERR_NO_ERROR) |
|
284 return error; |
|
285 |
|
286 RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); |
|
287 plugin->loadURL("POST", makeURLString(url), target, headerFields, postData, false, 0); |
|
288 return NPERR_NO_ERROR; |
|
289 } |
|
290 |
|
291 static NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList) |
|
292 { |
|
293 notImplemented(); |
|
294 return NPERR_GENERIC_ERROR; |
|
295 } |
|
296 |
|
297 static NPError NPN_NewStream(NPP instance, NPMIMEType type, const char* target, NPStream** stream) |
|
298 { |
|
299 notImplemented(); |
|
300 return NPERR_GENERIC_ERROR; |
|
301 } |
|
302 |
|
303 static int32_t NPN_Write(NPP instance, NPStream* stream, int32_t len, void* buffer) |
|
304 { |
|
305 notImplemented(); |
|
306 return -1; |
|
307 } |
|
308 |
|
309 static NPError NPN_DestroyStream(NPP npp, NPStream* stream, NPReason reason) |
|
310 { |
|
311 RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); |
|
312 |
|
313 return plugin->destroyStream(stream, reason); |
|
314 } |
|
315 |
|
316 static void NPN_Status(NPP instance, const char* message) |
|
317 { |
|
318 notImplemented(); |
|
319 } |
|
320 |
|
321 static const char* NPN_UserAgent(NPP npp) |
|
322 { |
|
323 if (!npp) |
|
324 return 0; |
|
325 |
|
326 RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); |
|
327 return plugin->userAgent(); |
|
328 } |
|
329 |
|
330 static void* NPN_MemAlloc(uint32_t size) |
|
331 { |
|
332 // We could use fastMalloc here, but there might be plug-ins that mix NPN_MemAlloc/NPN_MemFree with malloc and free, |
|
333 // so having them be equivalent seems like a good idea. |
|
334 return malloc(size); |
|
335 } |
|
336 |
|
337 static void NPN_MemFree(void* ptr) |
|
338 { |
|
339 // We could use fastFree here, but there might be plug-ins that mix NPN_MemAlloc/NPN_MemFree with malloc and free, |
|
340 // so having them be equivalent seems like a good idea. |
|
341 free(ptr); |
|
342 } |
|
343 |
|
344 static uint32_t NPN_MemFlush(uint32_t size) |
|
345 { |
|
346 return 0; |
|
347 } |
|
348 |
|
349 static void NPN_ReloadPlugins(NPBool reloadPages) |
|
350 { |
|
351 notImplemented(); |
|
352 } |
|
353 |
|
354 static JRIEnv* NPN_GetJavaEnv(void) |
|
355 { |
|
356 notImplemented(); |
|
357 return 0; |
|
358 } |
|
359 |
|
360 static jref NPN_GetJavaPeer(NPP instance) |
|
361 { |
|
362 notImplemented(); |
|
363 return 0; |
|
364 } |
|
365 |
|
366 static NPError NPN_GetURLNotify(NPP npp, const char* url, const char* target, void* notifyData) |
|
367 { |
|
368 if (!url) |
|
369 return NPERR_GENERIC_ERROR; |
|
370 |
|
371 RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); |
|
372 plugin->loadURL("GET", makeURLString(url), target, HTTPHeaderMap(), Vector<char>(), true, notifyData); |
|
373 |
|
374 return NPERR_NO_ERROR; |
|
375 } |
|
376 |
|
377 static NPError NPN_PostURLNotify(NPP npp, const char* url, const char* target, uint32_t len, const char* buf, NPBool file, void* notifyData) |
|
378 { |
|
379 HTTPHeaderMap headerFields; |
|
380 Vector<char> postData; |
|
381 NPError error = parsePostBuffer(file, buf, len, true, headerFields, postData); |
|
382 if (error != NPERR_NO_ERROR) |
|
383 return error; |
|
384 |
|
385 RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); |
|
386 plugin->loadURL("POST", makeURLString(url), target, headerFields, postData, true, notifyData); |
|
387 return NPERR_NO_ERROR; |
|
388 } |
|
389 |
|
390 static NPError NPN_GetValue(NPP npp, NPNVariable variable, void *value) |
|
391 { |
|
392 switch (variable) { |
|
393 case NPNVWindowNPObject: { |
|
394 RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); |
|
395 |
|
396 NPObject* windowNPObject = plugin->windowScriptNPObject(); |
|
397 *(NPObject**)value = windowNPObject; |
|
398 break; |
|
399 } |
|
400 case NPNVPluginElementNPObject: { |
|
401 RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); |
|
402 |
|
403 NPObject* pluginElementNPObject = plugin->pluginElementNPObject(); |
|
404 *(NPObject**)value = pluginElementNPObject; |
|
405 break; |
|
406 } |
|
407 #if PLATFORM(MAC) |
|
408 case NPNVsupportsCoreGraphicsBool: |
|
409 // Always claim to support the Core Graphics drawing model. |
|
410 *(NPBool *)value = true; |
|
411 break; |
|
412 |
|
413 case NPNVsupportsCocoaBool: |
|
414 // Always claim to support the Cocoa event model. |
|
415 *(NPBool *)value = true; |
|
416 break; |
|
417 #endif |
|
418 default: |
|
419 notImplemented(); |
|
420 return NPERR_GENERIC_ERROR; |
|
421 } |
|
422 |
|
423 return NPERR_NO_ERROR; |
|
424 } |
|
425 |
|
426 static NPError NPN_SetValue(NPP npp, NPPVariable variable, void *value) |
|
427 { |
|
428 switch (variable) { |
|
429 #if PLATFORM(MAC) |
|
430 case NPPVpluginDrawingModel: { |
|
431 RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); |
|
432 |
|
433 NPDrawingModel drawingModel = static_cast<NPDrawingModel>(reinterpret_cast<uintptr_t>(value)); |
|
434 return plugin->setDrawingModel(drawingModel); |
|
435 } |
|
436 |
|
437 case NPPVpluginEventModel: { |
|
438 RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); |
|
439 |
|
440 NPEventModel eventModel = static_cast<NPEventModel>(reinterpret_cast<uintptr_t>(value)); |
|
441 return plugin->setEventModel(eventModel); |
|
442 } |
|
443 #endif |
|
444 |
|
445 default: |
|
446 notImplemented(); |
|
447 return NPERR_GENERIC_ERROR; |
|
448 } |
|
449 |
|
450 return NPERR_NO_ERROR; |
|
451 } |
|
452 |
|
453 static void NPN_InvalidateRect(NPP npp, NPRect* invalidRect) |
|
454 { |
|
455 RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); |
|
456 plugin->invalidate(invalidRect); |
|
457 } |
|
458 |
|
459 static void NPN_InvalidateRegion(NPP npp, NPRegion invalidRegion) |
|
460 { |
|
461 // FIXME: We could at least figure out the bounding rectangle of the invalid region. |
|
462 RefPtr<NetscapePlugin> plugin = NetscapePlugin::fromNPP(npp); |
|
463 plugin->invalidate(0); |
|
464 } |
|
465 |
|
466 static void NPN_ForceRedraw(NPP instance) |
|
467 { |
|
468 notImplemented(); |
|
469 } |
|
470 |
|
471 static NPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name) |
|
472 { |
|
473 return static_cast<NPIdentifier>(IdentifierRep::get(name)); |
|
474 } |
|
475 |
|
476 static void NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount, NPIdentifier *identifiers) |
|
477 { |
|
478 ASSERT(names); |
|
479 ASSERT(identifiers); |
|
480 |
|
481 if (!names || !identifiers) |
|
482 return; |
|
483 |
|
484 for (int32_t i = 0; i < nameCount; ++i) |
|
485 identifiers[i] = NPN_GetStringIdentifier(names[i]); |
|
486 } |
|
487 |
|
488 static NPIdentifier NPN_GetIntIdentifier(int32_t intid) |
|
489 { |
|
490 return static_cast<NPIdentifier>(IdentifierRep::get(intid)); |
|
491 } |
|
492 |
|
493 static bool NPN_IdentifierIsString(NPIdentifier identifier) |
|
494 { |
|
495 return static_cast<IdentifierRep*>(identifier)->isString(); |
|
496 } |
|
497 |
|
498 static NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier) |
|
499 { |
|
500 const char* string = static_cast<IdentifierRep*>(identifier)->string(); |
|
501 if (!string) |
|
502 return 0; |
|
503 |
|
504 uint32_t stringLength = strlen(string); |
|
505 char* utf8String = static_cast<char*>(NPN_MemAlloc(stringLength + 1)); |
|
506 memcpy(utf8String, string, stringLength); |
|
507 utf8String[stringLength] = '\0'; |
|
508 |
|
509 return utf8String; |
|
510 } |
|
511 |
|
512 static int32_t NPN_IntFromIdentifier(NPIdentifier identifier) |
|
513 { |
|
514 return static_cast<IdentifierRep*>(identifier)->number(); |
|
515 } |
|
516 |
|
517 static NPObject* NPN_CreateObject(NPP npp, NPClass *npClass) |
|
518 { |
|
519 return createNPObject(npp, npClass); |
|
520 } |
|
521 |
|
522 static NPObject *NPN_RetainObject(NPObject *npObject) |
|
523 { |
|
524 retainNPObject(npObject); |
|
525 return npObject; |
|
526 } |
|
527 |
|
528 static void NPN_ReleaseObject(NPObject *npObject) |
|
529 { |
|
530 releaseNPObject(npObject); |
|
531 } |
|
532 |
|
533 static bool NPN_Invoke(NPP npp, NPObject *npobj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result) |
|
534 { |
|
535 notImplemented(); |
|
536 return false; |
|
537 } |
|
538 |
|
539 static bool NPN_InvokeDefault(NPP npp, NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result) |
|
540 { |
|
541 notImplemented(); |
|
542 return false; |
|
543 } |
|
544 |
|
545 static bool NPN_Evaluate(NPP npp, NPObject *npobj, NPString *script, NPVariant *result) |
|
546 { |
|
547 notImplemented(); |
|
548 return false; |
|
549 } |
|
550 |
|
551 static bool NPN_GetProperty(NPP npp, NPObject *npObject, NPIdentifier propertyName, NPVariant *result) |
|
552 { |
|
553 if (npObject->_class->hasProperty && npObject->_class->getProperty) { |
|
554 if (npObject->_class->hasProperty(npObject, propertyName)) |
|
555 return npObject->_class->getProperty(npObject, propertyName, result); |
|
556 } |
|
557 |
|
558 VOID_TO_NPVARIANT(*result); |
|
559 return false; |
|
560 } |
|
561 |
|
562 static bool NPN_SetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName, const NPVariant *value) |
|
563 { |
|
564 notImplemented(); |
|
565 return false; |
|
566 } |
|
567 |
|
568 static bool NPN_RemoveProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName) |
|
569 { |
|
570 notImplemented(); |
|
571 return false; |
|
572 } |
|
573 |
|
574 static bool NPN_HasProperty(NPP npp, NPObject *npObject, NPIdentifier propertyName) |
|
575 { |
|
576 if (npObject->_class->hasProperty) |
|
577 return npObject->_class->hasProperty(npObject, propertyName); |
|
578 |
|
579 return false; |
|
580 } |
|
581 |
|
582 static bool NPN_HasMethod(NPP npp, NPObject *npobj, NPIdentifier methodName) |
|
583 { |
|
584 notImplemented(); |
|
585 return false; |
|
586 } |
|
587 |
|
588 static void NPN_ReleaseVariantValue(NPVariant *variant) |
|
589 { |
|
590 releaseNPVariantValue(variant); |
|
591 } |
|
592 |
|
593 static void NPN_SetException(NPObject *npobj, const NPUTF8 *message) |
|
594 { |
|
595 notImplemented(); |
|
596 } |
|
597 |
|
598 static void NPN_PushPopupsEnabledState(NPP instance, NPBool enabled) |
|
599 { |
|
600 notImplemented(); |
|
601 } |
|
602 |
|
603 static void NPN_PopPopupsEnabledState(NPP instance) |
|
604 { |
|
605 notImplemented(); |
|
606 } |
|
607 |
|
608 static bool NPN_Enumerate(NPP npp, NPObject *npobj, NPIdentifier **identifier, uint32_t *count) |
|
609 { |
|
610 notImplemented(); |
|
611 return false; |
|
612 } |
|
613 |
|
614 static void NPN_PluginThreadAsyncCall(NPP instance, void (*func) (void *), void *userData) |
|
615 { |
|
616 notImplemented(); |
|
617 } |
|
618 |
|
619 static bool NPN_Construct(NPP npp, NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result) |
|
620 { |
|
621 notImplemented(); |
|
622 return false; |
|
623 } |
|
624 |
|
625 static NPError NPN_GetValueForURL(NPP instance, NPNURLVariable variable, const char *url, char **value, uint32_t *len) |
|
626 { |
|
627 notImplemented(); |
|
628 return NPERR_GENERIC_ERROR; |
|
629 } |
|
630 |
|
631 static NPError NPN_SetValueForURL(NPP instance, NPNURLVariable variable, const char *url, const char *value, uint32_t len) |
|
632 { |
|
633 notImplemented(); |
|
634 return NPERR_GENERIC_ERROR; |
|
635 } |
|
636 |
|
637 static NPError NPN_GetAuthenticationInfo(NPP instance, const char *protocol, const char *host, int32_t port, const char *scheme, |
|
638 const char *realm, char **username, uint32_t *ulen, char **password, uint32_t *plen) |
|
639 { |
|
640 notImplemented(); |
|
641 return NPERR_GENERIC_ERROR; |
|
642 } |
|
643 |
|
644 static uint32_t NPN_ScheduleTimer(NPP instance, uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID)) |
|
645 { |
|
646 notImplemented(); |
|
647 return NPERR_GENERIC_ERROR; |
|
648 } |
|
649 |
|
650 static void NPN_UnscheduleTimer(NPP instance, uint32_t timerID) |
|
651 { |
|
652 notImplemented(); |
|
653 } |
|
654 |
|
655 static NPError NPN_PopUpContextMenu(NPP instance, NPMenu* menu) |
|
656 { |
|
657 notImplemented(); |
|
658 return NPERR_GENERIC_ERROR; |
|
659 } |
|
660 |
|
661 static NPBool NPN_ConvertPoint(NPP instance, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace) |
|
662 { |
|
663 notImplemented(); |
|
664 return false; |
|
665 } |
|
666 |
|
667 static void initializeBrowserFuncs(NPNetscapeFuncs &netscapeFuncs) |
|
668 { |
|
669 netscapeFuncs.size = sizeof(NPNetscapeFuncs); |
|
670 netscapeFuncs.version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; |
|
671 |
|
672 netscapeFuncs.geturl = NPN_GetURL; |
|
673 netscapeFuncs.posturl = NPN_PostURL; |
|
674 netscapeFuncs.requestread = NPN_RequestRead; |
|
675 netscapeFuncs.newstream = NPN_NewStream; |
|
676 netscapeFuncs.write = NPN_Write; |
|
677 netscapeFuncs.destroystream = NPN_DestroyStream; |
|
678 netscapeFuncs.status = NPN_Status; |
|
679 netscapeFuncs.uagent = NPN_UserAgent; |
|
680 netscapeFuncs.memalloc = NPN_MemAlloc; |
|
681 netscapeFuncs.memfree = NPN_MemFree; |
|
682 netscapeFuncs.memflush = NPN_MemFlush; |
|
683 netscapeFuncs.reloadplugins = NPN_ReloadPlugins; |
|
684 netscapeFuncs.getJavaEnv = NPN_GetJavaEnv; |
|
685 netscapeFuncs.getJavaPeer = NPN_GetJavaPeer; |
|
686 netscapeFuncs.geturlnotify = NPN_GetURLNotify; |
|
687 netscapeFuncs.posturlnotify = NPN_PostURLNotify; |
|
688 netscapeFuncs.getvalue = NPN_GetValue; |
|
689 netscapeFuncs.setvalue = NPN_SetValue; |
|
690 netscapeFuncs.invalidaterect = NPN_InvalidateRect; |
|
691 netscapeFuncs.invalidateregion = NPN_InvalidateRegion; |
|
692 netscapeFuncs.forceredraw = NPN_ForceRedraw; |
|
693 |
|
694 netscapeFuncs.getstringidentifier = NPN_GetStringIdentifier; |
|
695 netscapeFuncs.getstringidentifiers = NPN_GetStringIdentifiers; |
|
696 netscapeFuncs.getintidentifier = NPN_GetIntIdentifier; |
|
697 netscapeFuncs.identifierisstring = NPN_IdentifierIsString; |
|
698 netscapeFuncs.utf8fromidentifier = NPN_UTF8FromIdentifier; |
|
699 netscapeFuncs.intfromidentifier = NPN_IntFromIdentifier; |
|
700 netscapeFuncs.createobject = NPN_CreateObject; |
|
701 netscapeFuncs.retainobject = NPN_RetainObject; |
|
702 netscapeFuncs.releaseobject = NPN_ReleaseObject; |
|
703 netscapeFuncs.invoke = NPN_Invoke; |
|
704 netscapeFuncs.invokeDefault = NPN_InvokeDefault; |
|
705 netscapeFuncs.evaluate = NPN_Evaluate; |
|
706 netscapeFuncs.getproperty = NPN_GetProperty; |
|
707 netscapeFuncs.setproperty = NPN_SetProperty; |
|
708 netscapeFuncs.removeproperty = NPN_RemoveProperty; |
|
709 netscapeFuncs.hasproperty = NPN_HasProperty; |
|
710 netscapeFuncs.hasmethod = NPN_HasMethod; |
|
711 netscapeFuncs.releasevariantvalue = NPN_ReleaseVariantValue; |
|
712 netscapeFuncs.setexception = NPN_SetException; |
|
713 netscapeFuncs.pushpopupsenabledstate = NPN_PushPopupsEnabledState; |
|
714 netscapeFuncs.poppopupsenabledstate = NPN_PopPopupsEnabledState; |
|
715 netscapeFuncs.enumerate = NPN_Enumerate; |
|
716 netscapeFuncs.pluginthreadasynccall = NPN_PluginThreadAsyncCall; |
|
717 netscapeFuncs.construct = NPN_Construct; |
|
718 netscapeFuncs.getvalueforurl = NPN_GetValueForURL; |
|
719 netscapeFuncs.setvalueforurl = NPN_SetValueForURL; |
|
720 netscapeFuncs.getauthenticationinfo = NPN_GetAuthenticationInfo; |
|
721 netscapeFuncs.scheduletimer = NPN_ScheduleTimer; |
|
722 netscapeFuncs.unscheduletimer = NPN_UnscheduleTimer; |
|
723 netscapeFuncs.popupcontextmenu = NPN_PopUpContextMenu; |
|
724 netscapeFuncs.convertpoint = NPN_ConvertPoint; |
|
725 } |
|
726 |
|
727 NPNetscapeFuncs* netscapeBrowserFuncs() |
|
728 { |
|
729 static NPNetscapeFuncs netscapeFuncs; |
|
730 static bool initialized = false; |
|
731 |
|
732 if (!initialized) { |
|
733 initializeBrowserFuncs(netscapeFuncs); |
|
734 initialized = true; |
|
735 } |
|
736 |
|
737 return &netscapeFuncs; |
|
738 } |
|
739 |
|
740 } // namespace WebKit |