📄 webkit.mm
字号:
MacPostControlCreate(pos, size); HIViewSetVisible( m_peer->GetControlRef(), true ); [m_webView setHidden:false];#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 if ( UMAGetSystemVersion() >= 0x1030 ) HIViewChangeFeatures( m_peer->GetControlRef() , kHIViewIsOpaque , 0 ) ;#endif InstallControlEventHandler( m_peer->GetControlRef() , GetwxWebKitCtrlEventHandlerUPP(), GetEventTypeCount(eventList), eventList, this, (EventHandlerRef *)&m_webKitCtrlEventHandler);#endif // Register event listener interfaces MyFrameLoadMonitor* myFrameLoadMonitor = [[MyFrameLoadMonitor alloc] initWithWxWindow: this]; [m_webView setFrameLoadDelegate:myFrameLoadMonitor]; // this is used to veto page loads, etc. MyPolicyDelegate* myPolicyDelegate = [[MyPolicyDelegate alloc] initWithWxWindow: this]; [m_webView setPolicyDelegate:myPolicyDelegate]; LoadURL(m_currentURL); return true;}wxWebKitCtrl::~wxWebKitCtrl(){}// ----------------------------------------------------------------------------// public methods// ----------------------------------------------------------------------------void wxWebKitCtrl::LoadURL(const wxString &url){ if( !m_webView ) return; [[m_webView mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:wxNSStringWithWxString(url)]]]; m_currentURL = url;}bool wxWebKitCtrl::CanGoBack(){ if ( !m_webView ) return false; return [m_webView canGoBack];}bool wxWebKitCtrl::CanGoForward(){ if ( !m_webView ) return false; return [m_webView canGoForward];}bool wxWebKitCtrl::GoBack(){ if ( !m_webView ) return false; bool result = [(WebView*)m_webView goBack]; return result;}bool wxWebKitCtrl::GoForward(){ if ( !m_webView ) return false; bool result = [(WebView*)m_webView goForward]; return result;}void wxWebKitCtrl::Reload(){ if ( !m_webView ) return; [[m_webView mainFrame] reload];}void wxWebKitCtrl::Stop(){ if ( !m_webView ) return; [[m_webView mainFrame] stopLoading];}bool wxWebKitCtrl::CanGetPageSource(){ if ( !m_webView ) return false; WebDataSource* dataSource = [[m_webView mainFrame] dataSource]; return ( [[dataSource representation] canProvideDocumentSource] );}wxString wxWebKitCtrl::GetPageSource(){ if (CanGetPageSource()){ WebDataSource* dataSource = [[m_webView mainFrame] dataSource]; return wxStringWithNSString( [[dataSource representation] documentSource] ); } return wxEmptyString;}wxString wxWebKitCtrl::GetSelection(){ if ( !m_webView ) return wxEmptyString; NSString* selectedText = [[m_webView selectedDOMRange] toString]; return wxStringWithNSString( selectedText );}bool wxWebKitCtrl::CanIncreaseTextSize(){ if ( !m_webView ) return false; if ([m_webView canMakeTextLarger]) return true; else return false;}void wxWebKitCtrl::IncreaseTextSize(){ if ( !m_webView ) return; if (CanIncreaseTextSize()) [m_webView makeTextLarger:(WebView*)m_webView];}bool wxWebKitCtrl::CanDecreaseTextSize(){ if ( !m_webView ) return false; if ([m_webView canMakeTextSmaller]) return true; else return false;}void wxWebKitCtrl::DecreaseTextSize(){ if ( !m_webView ) return; if (CanDecreaseTextSize()) [m_webView makeTextSmaller:(WebView*)m_webView];}void wxWebKitCtrl::SetPageSource(const wxString& source, const wxString& baseUrl){ if ( !m_webView ) return; [[m_webView mainFrame] loadHTMLString:(NSString*)wxNSStringWithWxString( source ) baseURL:[NSURL URLWithString:wxNSStringWithWxString( baseUrl )]];}void wxWebKitCtrl::Print(bool showPrompt){ if ( !m_webView ) return; id view = [[[m_webView mainFrame] frameView] documentView]; NSPrintOperation *op = [NSPrintOperation printOperationWithView:view printInfo: [NSPrintInfo sharedPrintInfo]]; if (showPrompt){ [op setShowsPrintPanel: showPrompt]; // in my tests, the progress bar always freezes and it stops the whole print operation. // do not turn this to true unless there is a workaround for the bug. [op setShowsProgressPanel: false]; } // Print it. [op runOperation]; }void wxWebKitCtrl::MakeEditable(bool enable){ if ( !m_webView ) return; [m_webView setEditable:enable ];}bool wxWebKitCtrl::IsEditable(){ if ( !m_webView ) return false; return [m_webView isEditable];}int wxWebKitCtrl::GetScrollPos(){ id result = [[m_webView windowScriptObject] evaluateWebScript:@"document.body.scrollTop"]; return [result intValue];} void wxWebKitCtrl::SetScrollPos(int pos){ if ( !m_webView ) return; wxString javascript; javascript.Printf(wxT("document.body.scrollTop = %d;"), pos); [[m_webView windowScriptObject] evaluateWebScript:(NSString*)wxNSStringWithWxString( javascript )];}wxString wxWebKitCtrl::RunScript(const wxString& javascript){ if ( !m_webView ) return wxEmptyString; id result = [[m_webView windowScriptObject] evaluateWebScript:(NSString*)wxNSStringWithWxString( javascript )]; NSString* resultAsString; wxString resultAsWxString = wxEmptyString; NSString* className = NSStringFromClass([result class]); if ([className isEqualToString:@"NSCFNumber"]) resultAsString = [NSString stringWithFormat:@"%@", result]; else if ([className isEqualToString:@"NSCFString"]) resultAsString = result; else if ([className isEqualToString:@"NSCFBoolean"]){ if ([result boolValue]) resultAsString = @"true"; else resultAsString = @"false"; } else if ([className isEqualToString:@"WebScriptObject"]) resultAsString = [result stringRepresentation]; else fprintf(stderr, "wxWebKitCtrl::RunScript - Unexpected return type: %s!\n", [className UTF8String]); resultAsWxString = wxStringWithNSString( resultAsString ); return resultAsWxString;}void wxWebKitCtrl::OnSize(wxSizeEvent &event){ // This is a nasty hack because WebKit seems to lose its position when it is embedded // in a control that is not itself the content view for a TLW. // I put it in OnSize because these calcs are not perfect, and in fact are basically // guesses based on reverse engineering, so it's best to give people the option of // overriding OnSize with their own calcs if need be. // I also left some test debugging print statements as a convenience if a(nother) // problem crops up. wxWindow* tlw = MacGetTopLevelWindow(); NSRect frame = [m_webView frame]; NSRect bounds = [m_webView bounds]; #if DEBUG_WEBKIT_SIZING fprintf(stderr,"Carbon window x=%d, y=%d, width=%d, height=%d\n", GetPosition().x, GetPosition().y, GetSize().x, GetSize().y); fprintf(stderr, "Cocoa window frame x=%G, y=%G, width=%G, height=%G\n", frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); fprintf(stderr, "Cocoa window bounds x=%G, y=%G, width=%G, height=%G\n", bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height);#endif // This must be the case that Apple tested with, because well, in this one case // we don't need to do anything! It just works. ;) if (GetParent() == tlw){ return; } // since we no longer use parent coordinates, we always want 0,0. int x = 0; int y = 0; HIRect rect; rect.origin.x = x; rect.origin.y = y;#if DEBUG_WEBKIT_SIZING printf("Before conversion, origin is: x = %d, y = %d\n", x, y);#endif // NB: In most cases, when calling HIViewConvertRect, what people want is to use GetRootControl(), // and this tripped me up at first. But in fact, what we want is the root view, because we need to // make the y origin relative to the very top of the window, not its contents, since we later flip // the y coordinate for Cocoa. HIViewConvertRect (&rect, m_peer->GetControlRef(), HIViewGetRoot( (WindowRef) MacGetTopLevelWindowRef() ) ); x = (int)rect.origin.x; y = (int)rect.origin.y;#if DEBUG_WEBKIT_SIZING printf("Moving Cocoa frame origin to: x = %d, y = %d\n", x, y);#endif if (tlw){ //flip the y coordinate to convert to Cocoa coordinates y = tlw->GetSize().y - ((GetSize().y) + y); }#if DEBUG_WEBKIT_SIZING printf("y = %d after flipping value\n", y);#endif frame.origin.x = x; frame.origin.y = y; [m_webView setFrame:frame]; if (IsShown()) [(WebView*)m_webView display]; event.Skip();}void wxWebKitCtrl::MacVisibilityChanged(){ bool isHidden = !IsControlVisible( m_peer->GetControlRef()); if (!isHidden) [(WebView*)m_webView display]; [m_webView setHidden:isHidden];}//------------------------------------------------------------// Listener interfaces//------------------------------------------------------------// NB: I'm still tracking this down, but it appears the Cocoa window// still has these events fired on it while the Carbon control is being// destroyed. Therefore, we must be careful to check both the existence// of the Carbon control and the event handler before firing events.@implementation MyFrameLoadMonitor- initWithWxWindow: (wxWebKitCtrl*)inWindow{ [super init]; webKitWindow = inWindow; // non retained return self;}- (void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame{ if (webKitWindow && frame == [sender mainFrame]){ NSString *url = [[[[frame provisionalDataSource] request] URL] absoluteString]; wxWebKitStateChangedEvent thisEvent(webKitWindow); thisEvent.SetState(wxWEBKIT_STATE_NEGOTIATING); thisEvent.SetURL( wxStringWithNSString( url ) ); if (webKitWindow->GetEventHandler()) webKitWindow->GetEventHandler()->ProcessEvent( thisEvent ); }}- (void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame{ if (webKitWindow && frame == [sender mainFrame]){ NSString *url = [[[[frame dataSource] request] URL] absoluteString]; wxWebKitStateChangedEvent thisEvent(webKitWindow); thisEvent.SetState(wxWEBKIT_STATE_TRANSFERRING); thisEvent.SetURL( wxStringWithNSString( url ) ); if (webKitWindow->GetEventHandler()) webKitWindow->GetEventHandler()->ProcessEvent( thisEvent ); }}- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame{ if (webKitWindow && frame == [sender mainFrame]){ NSString *url = [[[[frame dataSource] request] URL] absoluteString]; wxWebKitStateChangedEvent thisEvent(webKitWindow); thisEvent.SetState(wxWEBKIT_STATE_STOP); thisEvent.SetURL( wxStringWithNSString( url ) ); if (webKitWindow->GetEventHandler()) webKitWindow->GetEventHandler()->ProcessEvent( thisEvent ); }}- (void)webView:(WebView *)sender didFailLoadWithError:(NSError*) error forFrame:(WebFrame *)frame{ if (webKitWindow && frame == [sender mainFrame]){ NSString *url = [[[[frame dataSource] request] URL] absoluteString]; wxWebKitStateChangedEvent thisEvent(webKitWindow); thisEvent.SetState(wxWEBKIT_STATE_FAILED); thisEvent.SetURL( wxStringWithNSString( url ) ); if (webKitWindow->GetEventHandler()) webKitWindow->GetEventHandler()->ProcessEvent( thisEvent ); }}- (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError*) error forFrame:(WebFrame *)frame{ if (webKitWindow && frame == [sender mainFrame]){ NSString *url = [[[[frame provisionalDataSource] request] URL] absoluteString]; wxWebKitStateChangedEvent thisEvent(webKitWindow); thisEvent.SetState(wxWEBKIT_STATE_FAILED); thisEvent.SetURL( wxStringWithNSString( url ) ); if (webKitWindow->GetEventHandler()) webKitWindow->GetEventHandler()->ProcessEvent( thisEvent ); }}- (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame{ if (webKitWindow && frame == [sender mainFrame]){ webKitWindow->SetPageTitle(wxStringWithNSString( title )); }}@end@implementation MyPolicyDelegate- initWithWxWindow: (wxWebKitCtrl*)inWindow{ [super init]; webKitWindow = inWindow; // non retained return self;}- (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id<WebPolicyDecisionListener>)listener{ wxWebKitBeforeLoadEvent thisEvent(webKitWindow); // Get the navigation type. NSNumber *n = [actionInformation objectForKey:WebActionNavigationTypeKey]; int actionType = [n intValue]; thisEvent.SetNavigationType( wxNavTypeFromWebNavType(actionType) ); NSString *url = [[request URL] absoluteString]; thisEvent.SetURL( wxStringWithNSString( url ) ); if (webKitWindow && webKitWindow->GetEventHandler()) webKitWindow->GetEventHandler()->ProcessEvent(thisEvent); if (thisEvent.IsCancelled()) [listener ignore]; else [listener use];}@end#endif //wxUSE_WEBKIT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -