#import "OakHTMLOutputView.h"
#import "browser/HOStatusBar.h"
#import "helpers/HOAutoScroll.h"
#import "helpers/HOJSBridge.h"
#import
#import
extern NSString* const kCommandRunnerURLScheme; // from HTMLOutput.h
@interface OakHTMLOutputView ()
{
OBJC_WATCH_LEAKS(OakHTMLOutputView);
}
@property (nonatomic) BOOL runningCommand;
@property (nonatomic) HOAutoScroll* autoScrollHelper;
@property (nonatomic) std::map environment;
@property (nonatomic) NSRect pendingVisibleRect;
@end
@implementation OakHTMLOutputView
- (void)loadRequest:(NSURLRequest*)aRequest environment:(std::map const&)anEnvironment autoScrolls:(BOOL)flag
{
if(flag)
{
self.autoScrollHelper = [HOAutoScroll new];
self.autoScrollHelper.webFrame = self.webView.mainFrame.frameView;
}
self.environment = anEnvironment;
self.runningCommand = [[[aRequest URL] scheme] isEqualToString:kCommandRunnerURLScheme];
[self.webView.mainFrame loadRequest:aRequest];
}
- (void)stopLoading
{
[self.webView.mainFrame stopLoading];
}
- (void)loadHTMLString:(NSString*)someHTML
{
self.pendingVisibleRect = [[[[self.webView mainFrame] frameView] documentView] visibleRect];
[[self.webView mainFrame] loadHTMLString:someHTML baseURL:[NSURL fileURLWithPath:NSHomeDirectory()]];
}
// =======================
// = Frame Load Delegate =
// =======================
- (void)webView:(WebView*)sender didStartProvisionalLoadForFrame:(WebFrame*)frame
{
self.statusBar.isBusy = YES;
if(NSString* scheme = [[[[[self.webView mainFrame] provisionalDataSource] request] URL] scheme])
[self setUpdatesProgress:![scheme isEqualToString:kCommandRunnerURLScheme]];
}
- (void)webView:(WebView*)sender didClearWindowObject:(WebScriptObject*)windowScriptObject forFrame:(WebFrame*)frame
{
NSString* scheme = [[[[[self.webView mainFrame] dataSource] request] URL] scheme];
if([@[ kCommandRunnerURLScheme, @"tm-file", @"file" ] containsObject:scheme])
{
HOJSBridge* bridge = [HOJSBridge new];
[bridge setDelegate:self.statusBar];
[bridge setEnvironment:_environment];
[windowScriptObject setValue:bridge forKey:@"TextMate"];
}
}
- (void)webView:(WebView*)sender didFinishLoadForFrame:(WebFrame*)frame
{
self.runningCommand = NO;
self.autoScrollHelper = nil;
// Sending goBack:/goForward: to a WebView does not call this WebFrameLoadDelegate method
if(frame == [sender mainFrame])
{
[self webView:sender didClearWindowObject:[frame windowObject] forFrame:frame];
// This happens when we redirect to a PDF file
if(self.window.firstResponder == self.window)
{
NSRect rect = [sender frame];
for(NSView* view = [sender hitTest:NSMakePoint(NSMidX(rect), NSMidY(rect))]; view; view = [view superview])
{
if([view acceptsFirstResponder])
{
[self.window makeFirstResponder:view];
break;
}
}
}
}
if(!NSEqualRects(self.pendingVisibleRect, NSZeroRect))
[[[[self.webView mainFrame] frameView] documentView] scrollRectToVisible:self.pendingVisibleRect];
self.pendingVisibleRect = NSZeroRect;
[super webView:sender didFinishLoadForFrame:frame];
}
- (void)webView:(WebView*)sender didFailProvisionalLoadWithError:(NSError*)error forFrame:(WebFrame*)frame
{
self.runningCommand = NO;
self.autoScrollHelper = nil;
[super webView:sender didFailProvisionalLoadWithError:error forFrame:frame];
}
- (void)webView:(WebView*)sender didFailLoadWithError:(NSError*)error forFrame:(WebFrame*)frame
{
self.runningCommand = NO;
self.autoScrollHelper = nil;
[super webView:sender didFailLoadWithError:error forFrame:frame];
}
// =========================================
// = WebPolicyDelegate : Intercept txmt:// =
// =========================================
- (void)webView:(WebView*)sender decidePolicyForNavigationAction:(NSDictionary*)actionInformation request:(NSURLRequest*)request frame:(WebFrame*)frame decisionListener:(id )listener
{
if([NSURLConnection canHandleRequest:request])
{
[listener use];
}
else
{
[listener ignore];
NSURL* url = request.URL;
if([[url scheme] isEqualToString:@"txmt"])
{
auto projectUUID = _environment.find("TM_PROJECT_UUID");
if(projectUUID != _environment.end())
url = [NSURL URLWithString:[[url absoluteString] stringByAppendingFormat:@"&project=%@", [NSString stringWithCxxString:projectUUID->second]]];
[NSApp sendAction:@selector(handleTxMtURL:) to:nil from:url];
}
else
{
[[NSWorkspace sharedWorkspace] openURL:url];
}
}
}
// ====================
// = Printing Support =
// ====================
- (IBAction)printDocument:(id)sender
{
NSPrintOperation* printer = [NSPrintOperation printOperationWithView:self.webView.mainFrame.frameView.documentView];
[[printer printPanel] setOptions:[[printer printPanel] options] | NSPrintPanelShowsPaperSize | NSPrintPanelShowsOrientation];
NSPrintInfo* info = [printer printInfo];
NSRect display = NSIntersectionRect(info.imageablePageBounds, (NSRect){ NSZeroPoint, info.paperSize });
info.leftMargin = NSMinX(display);
info.rightMargin = info.paperSize.width - NSMaxX(display);
info.topMargin = info.paperSize.height - NSMaxY(display);
info.bottomMargin = NSMinY(display);
[printer runOperationModalForWindow:self.window delegate:nil didRunSelector:NULL contextInfo:nil];
}
@end