📄 webnetscapepluginview.mm
字号:
ASSERT(_isStarted); if (textInputFuncs && textInputFuncs->attributedSubstringFromRange) return textInputFuncs->attributedSubstringFromRange(plugin, theRange); return nil;}- (NSUInteger)characterIndexForPoint:(NSPoint)thePoint{ ASSERT(eventModel == NPEventModelCocoa); ASSERT(_isStarted); if (textInputFuncs && textInputFuncs->characterIndexForPoint) { // Convert the point to window coordinates NSPoint point = [[self window] convertScreenToBase:thePoint]; // And view coordinates point = [self convertPoint:point fromView:nil]; return textInputFuncs->characterIndexForPoint(plugin, point); } return NSNotFound;}- (void)doCommandBySelector:(SEL)aSelector{ ASSERT(eventModel == NPEventModelCocoa); ASSERT(_isStarted); if (textInputFuncs && textInputFuncs->doCommandBySelector) textInputFuncs->doCommandBySelector(plugin, aSelector);}- (NSRect)firstRectForCharacterRange:(NSRange)theRange{ ASSERT(eventModel == NPEventModelCocoa); ASSERT(_isStarted); if (textInputFuncs && textInputFuncs->firstRectForCharacterRange) { NSRect rect = textInputFuncs->firstRectForCharacterRange(plugin, theRange); // Convert the rect to window coordinates rect = [self convertRect:rect toView:nil]; // Convert the rect location to screen coordinates rect.origin = [[self window] convertBaseToScreen:rect.origin]; return rect; } return NSZeroRect;}// test for 10.4 because of <rdar://problem/4243463>#ifdef BUILDING_ON_TIGER- (long)conversationIdentifier{ return (long)self;}#else- (NSInteger)conversationIdentifier{ return (NSInteger)self;}#endif@end@implementation WebNetscapePluginView (WebNPPCallbacks)- (void)evaluateJavaScriptPluginRequest:(WebPluginRequest *)JSPluginRequest{ // FIXME: Is this isStarted check needed here? evaluateJavaScriptPluginRequest should not be called // if we are stopped since this method is called after a delay and we call // cancelPreviousPerformRequestsWithTarget inside of stop. if (!_isStarted) { return; } NSURL *URL = [[JSPluginRequest request] URL]; NSString *JSString = [URL _webkit_scriptIfJavaScriptURL]; ASSERT(JSString); NSString *result = [[self webFrame] _stringByEvaluatingJavaScriptFromString:JSString forceUserGesture:[JSPluginRequest isCurrentEventUserGesture]]; // Don't continue if stringByEvaluatingJavaScriptFromString caused the plug-in to stop. if (!_isStarted) { return; } if ([JSPluginRequest frameName] != nil) { // FIXME: If the result is a string, we probably want to put that string into the frame. if ([JSPluginRequest sendNotification]) { [self willCallPlugInFunction]; { JSC::JSLock::DropAllLocks dropAllLocks(false); [_pluginPackage.get() pluginFuncs]->urlnotify(plugin, [URL _web_URLCString], NPRES_DONE, [JSPluginRequest notifyData]); } [self didCallPlugInFunction]; } } else if ([result length] > 0) { // Don't call NPP_NewStream and other stream methods if there is no JS result to deliver. This is what Mozilla does. NSData *JSData = [result dataUsingEncoding:NSUTF8StringEncoding]; RefPtr<WebNetscapePluginStream> stream = WebNetscapePluginStream::create([NSURLRequest requestWithURL:URL], plugin, [JSPluginRequest sendNotification], [JSPluginRequest notifyData]); RetainPtr<NSURLResponse> response(AdoptNS, [[NSURLResponse alloc] initWithURL:URL MIMEType:@"text/plain" expectedContentLength:[JSData length] textEncodingName:nil]); stream->startStreamWithResponse(response.get()); stream->didReceiveData(0, static_cast<const char*>([JSData bytes]), [JSData length]); stream->didFinishLoading(0); }}- (void)webFrame:(WebFrame *)webFrame didFinishLoadWithReason:(NPReason)reason{ ASSERT(_isStarted); WebPluginRequest *pluginRequest = [_pendingFrameLoads.get() objectForKey:webFrame]; ASSERT(pluginRequest != nil); ASSERT([pluginRequest sendNotification]); [self willCallPlugInFunction]; { JSC::JSLock::DropAllLocks dropAllLocks(false); [_pluginPackage.get() pluginFuncs]->urlnotify(plugin, [[[pluginRequest request] URL] _web_URLCString], reason, [pluginRequest notifyData]); } [self didCallPlugInFunction]; [_pendingFrameLoads.get() removeObjectForKey:webFrame]; [webFrame _setInternalLoadDelegate:nil];}- (void)webFrame:(WebFrame *)webFrame didFinishLoadWithError:(NSError *)error{ NPReason reason = NPRES_DONE; if (error != nil) reason = WebNetscapePluginStream::reasonForError(error); [self webFrame:webFrame didFinishLoadWithReason:reason];}- (void)loadPluginRequest:(WebPluginRequest *)pluginRequest{ NSURLRequest *request = [pluginRequest request]; NSString *frameName = [pluginRequest frameName]; WebFrame *frame = nil; NSURL *URL = [request URL]; NSString *JSString = [URL _webkit_scriptIfJavaScriptURL]; ASSERT(frameName || JSString); if (frameName) { // FIXME - need to get rid of this window creation which // bypasses normal targeted link handling frame = kit(core([self webFrame])->loader()->findFrameForNavigation(frameName)); if (frame == nil) { WebView *currentWebView = [self webView]; NSDictionary *features = [[NSDictionary alloc] init]; WebView *newWebView = [[currentWebView _UIDelegateForwarder] webView:currentWebView createWebViewWithRequest:nil windowFeatures:features]; [features release]; if (!newWebView) { if ([pluginRequest sendNotification]) { [self willCallPlugInFunction]; { JSC::JSLock::DropAllLocks dropAllLocks(false); [_pluginPackage.get() pluginFuncs]->urlnotify(plugin, [[[pluginRequest request] URL] _web_URLCString], NPERR_GENERIC_ERROR, [pluginRequest notifyData]); } [self didCallPlugInFunction]; } return; } frame = [newWebView mainFrame]; core(frame)->tree()->setName(frameName); [[newWebView _UIDelegateForwarder] webViewShow:newWebView]; } } if (JSString) { ASSERT(frame == nil || [self webFrame] == frame); [self evaluateJavaScriptPluginRequest:pluginRequest]; } else { [frame loadRequest:request]; if ([pluginRequest sendNotification]) { // Check if another plug-in view or even this view is waiting for the frame to load. // If it is, tell it that the load was cancelled because it will be anyway. WebNetscapePluginView *view = [frame _internalLoadDelegate]; if (view != nil) { ASSERT([view isKindOfClass:[WebNetscapePluginView class]]); [view webFrame:frame didFinishLoadWithReason:NPRES_USER_BREAK]; } [_pendingFrameLoads.get() _webkit_setObject:pluginRequest forUncopiedKey:frame]; [frame _setInternalLoadDelegate:self]; } }}- (NPError)loadRequest:(NSMutableURLRequest *)request inTarget:(const char *)cTarget withNotifyData:(void *)notifyData sendNotification:(BOOL)sendNotification{ NSURL *URL = [request URL]; if (!URL) return NPERR_INVALID_URL; // Don't allow requests to be loaded when the document loader is stopping all loaders. if ([[self dataSource] _documentLoader]->isStopping()) return NPERR_GENERIC_ERROR; NSString *target = nil; if (cTarget) { // Find the frame given the target string. target = [NSString stringWithCString:cTarget encoding:NSISOLatin1StringEncoding]; } WebFrame *frame = [self webFrame]; // don't let a plugin start any loads if it is no longer part of a document that is being // displayed unless the loads are in the same frame as the plugin. if ([[self dataSource] _documentLoader] != core([self webFrame])->loader()->activeDocumentLoader() && (!cTarget || [frame findFrameNamed:target] != frame)) { return NPERR_GENERIC_ERROR; } NSString *JSString = [URL _webkit_scriptIfJavaScriptURL]; if (JSString != nil) { if (![[[self webView] preferences] isJavaScriptEnabled]) { // Return NPERR_GENERIC_ERROR if JS is disabled. This is what Mozilla does. return NPERR_GENERIC_ERROR; } else if (cTarget == NULL && _mode == NP_FULL) { // Don't allow a JavaScript request from a standalone plug-in that is self-targetted // because this can cause the user to be redirected to a blank page (3424039). return NPERR_INVALID_PARAM; } } else { if (!FrameLoader::canLoad(URL, String(), core([self webFrame])->document())) return NPERR_GENERIC_ERROR; } if (cTarget || JSString) { // Make when targetting a frame or evaluating a JS string, perform the request after a delay because we don't // want to potentially kill the plug-in inside of its URL request. if (JSString && target && [frame findFrameNamed:target] != frame) { // For security reasons, only allow JS requests to be made on the frame that contains the plug-in. return NPERR_INVALID_PARAM; } bool currentEventIsUserGesture = false; if (_eventHandler) currentEventIsUserGesture = _eventHandler->currentEventIsUserGesture(); WebPluginRequest *pluginRequest = [[WebPluginRequest alloc] initWithRequest:request frameName:target notifyData:notifyData sendNotification:sendNotification didStartFromUserGesture:currentEventIsUserGesture]; [self performSelector:@selector(loadPluginRequest:) withObject:pluginRequest afterDelay:0]; [pluginRequest release]; } else { RefPtr<WebNetscapePluginStream> stream = WebNetscapePluginStream::create(request, plugin, sendNotification, notifyData); streams.add(stream.get()); stream->start(); } return NPERR_NO_ERROR;}-(NPError)getURLNotify:(const char *)URLCString target:(const char *)cTarget notifyData:(void *)notifyData{ LOG(Plugins, "NPN_GetURLNotify: %s target: %s", URLCString, cTarget); NSMutableURLRequest *request = [self requestWithURLCString:URLCString]; return [self loadRequest:request inTarget:cTarget withNotifyData:notifyData sendNotification:YES];}-(NPError)getURL:(const char *)URLCString target:(const char *)cTarget{ LOG(Plugins, "NPN_GetURL: %s target: %s", URLCString, cTarget); NSMutableURLRequest *request = [self requestWithURLCString:URLCString]; return [self loadRequest:request inTarget:cTarget withNotifyData:NULL sendNotification:NO];}- (NPError)_postURL:(const char *)URLCString target:(const char *)target len:(UInt32)len buf:(const char *)buf file:(NPBool)file notifyData:(void *)notifyData sendNotification:(BOOL)sendNotification allowHeaders:(BOOL)allowHeaders{ if (!URLCString || !len || !buf) { return NPERR_INVALID_PARAM; } NSData *postData = nil; if (file) { // If we're posting a file, buf is either a file URL or a path to the file. NSString *bufString = (NSString *)CFStringCreateWithCString(kCFAllocatorDefault, buf, kCFStringEncodingWindowsLatin1); if (!bufString) { return NPERR_INVALID_PARAM; } NSURL *fileURL = [NSURL _web_URLWithDataAsString:bufString]; NSString *path; if ([fileURL isFileURL]) { path = [fileURL path]; } else { path = bufString; } postData = [NSData dataWithContentsOfFile:[path _webkit_fixedCarbonPOSIXPath]]; CFRelease(bufString); if (!postData) { return NPERR_FILE_NOT_FOUND; } } else { postData = [NSData dataWithBytes:buf length:len]; } if ([postData length] == 0) { return NPERR_INVALID_PARAM; } NSMutableURLRequest *request = [self requestWithURLCString:URLCString]; [request setHTTPMethod:@"POST"]; if (allowHeaders) { if ([postData _web_startsWithBlankLine]) { postData = [postData subdataWithRange:NSMakeRange(1, [postData length] - 1)]; } else { NSInteger location = [postData _web_locationAfterFirstBlankLine]; if (location != NSNotFound) { // If the blank line is somewhere in the middle of postData, everything before is the header. NSData *headerData = [postData subdataWithRange:NSMakeRange(0, location)]; NSMutableDictionary *header = [headerData _webkit_parseRFC822HeaderFields]; unsigned dataLength = [postData length] - location; // Sometimes plugins like to set Content-Length themselves when they post, // but WebFoundation does not like that. So we will remove the header // and instead truncate the data to the requested length. NSString *contentLength = [header objectForKey:@"Content-Length"]; if (contentLength != nil) dataLength = MIN((unsigned)[contentLength intValue], dataLength); [header removeObjectForKey:@"Content-Length"]; if ([header count] > 0) { [request setAllHTTPHeaderFields:header]; } // Everything after the blank line is the actual content of the POST. postData = [postData subdataWithRange:NSMakeRange(location, dataLength)]; } } if ([postData length] == 0) { return NPERR_INVALID_PARAM; } } // Plug-ins expect to receive unca
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -