Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add download support for MacGap #100

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions MacGap.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@

/* Begin PBXBuildFile section */
1495814F15C15CCC00E1CFE5 /* Notice.m in Sources */ = {isa = PBXBuildFile; fileRef = 1495814E15C15CCC00E1CFE5 /* Notice.m */; };
6FD6E4ED18C2D48C00DFFBE6 /* fonts.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FD6E4EC18C2D48C00DFFBE6 /* fonts.m */; };
24E5CE5718F83217006CC84A /* DownloadDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 24E5CE5618F83217006CC84A /* DownloadDelegate.m */; };
24E5CE5A18F8417A006CC84A /* DownloadInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 24E5CE5918F8417A006CC84A /* DownloadInfo.m */; };
6F169DA718CC332E005EDDF3 /* Command.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F169DA618CC332E005EDDF3 /* Command.m */; };
6F169DAA18CC35FD005EDDF3 /* CallbackDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F169DA918CC35FD005EDDF3 /* CallbackDelegate.m */; };
6F169DAC18CD8A4A005EDDF3 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6F169DAB18CD8A4A005EDDF3 /* JavaScriptCore.framework */; };
6F169DB118CD906F005EDDF3 /* MenuItemProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F169DAE18CD906F005EDDF3 /* MenuItemProxy.m */; };
6F169DB218CD906F005EDDF3 /* MenuProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6F169DB018CD906F005EDDF3 /* MenuProxy.m */; };
6FD6E4ED18C2D48C00DFFBE6 /* fonts.m in Sources */ = {isa = PBXBuildFile; fileRef = 6FD6E4EC18C2D48C00DFFBE6 /* fonts.m */; };
88746BEE14CCA435001E160E /* JSEventHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 88746BED14CCA435001E160E /* JSEventHelper.m */; };
88C0646014BDE10A00E4BCE2 /* Window.m in Sources */ = {isa = PBXBuildFile; fileRef = 88C0645F14BDE10A00E4BCE2 /* Window.m */; };
88C0646614BDEC5800E4BCE2 /* Window.xib in Resources */ = {isa = PBXBuildFile; fileRef = 88C0646414BDEC5800E4BCE2 /* Window.xib */; };
Expand Down Expand Up @@ -56,8 +58,10 @@
/* Begin PBXFileReference section */
1495814D15C15CCC00E1CFE5 /* Notice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Notice.h; path = Classes/Commands/Notice.h; sourceTree = "<group>"; };
1495814E15C15CCC00E1CFE5 /* Notice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Notice.m; path = Classes/Commands/Notice.m; sourceTree = "<group>"; };
6FD6E4EB18C2D48200DFFBE6 /* fonts.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = fonts.h; path = Classes/Commands/fonts.h; sourceTree = "<group>"; };
6FD6E4EC18C2D48C00DFFBE6 /* fonts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = fonts.m; path = Classes/Commands/fonts.m; sourceTree = "<group>"; };
24E5CE5518F83217006CC84A /* DownloadDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DownloadDelegate.h; path = Classes/DownloadDelegate.h; sourceTree = "<group>"; };
24E5CE5618F83217006CC84A /* DownloadDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DownloadDelegate.m; path = Classes/DownloadDelegate.m; sourceTree = "<group>"; };
24E5CE5818F8417A006CC84A /* DownloadInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DownloadInfo.h; path = Classes/DownloadInfo.h; sourceTree = "<group>"; };
24E5CE5918F8417A006CC84A /* DownloadInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DownloadInfo.m; path = Classes/DownloadInfo.m; sourceTree = "<group>"; };
6F169DA518CC332E005EDDF3 /* Command.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Command.h; path = Classes/Commands/Command.h; sourceTree = "<group>"; };
6F169DA618CC332E005EDDF3 /* Command.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = Command.m; path = Classes/Commands/Command.m; sourceTree = "<group>"; };
6F169DA818CC35FD005EDDF3 /* CallbackDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CallbackDelegate.h; path = Classes/CallbackDelegate.h; sourceTree = "<group>"; };
Expand All @@ -67,6 +71,8 @@
6F169DAE18CD906F005EDDF3 /* MenuItemProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MenuItemProxy.m; path = Classes/Commands/MenuItemProxy.m; sourceTree = "<group>"; };
6F169DAF18CD906F005EDDF3 /* MenuProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MenuProxy.h; path = Classes/Commands/MenuProxy.h; sourceTree = "<group>"; };
6F169DB018CD906F005EDDF3 /* MenuProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MenuProxy.m; path = Classes/Commands/MenuProxy.m; sourceTree = "<group>"; };
6FD6E4EB18C2D48200DFFBE6 /* fonts.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = fonts.h; path = Classes/Commands/fonts.h; sourceTree = "<group>"; };
6FD6E4EC18C2D48C00DFFBE6 /* fonts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = fonts.m; path = Classes/Commands/fonts.m; sourceTree = "<group>"; };
88746BEC14CCA435001E160E /* JSEventHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSEventHelper.h; path = Classes/JSEventHelper.h; sourceTree = "<group>"; };
88746BED14CCA435001E160E /* JSEventHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = JSEventHelper.m; path = Classes/JSEventHelper.m; sourceTree = "<group>"; };
88C0645E14BDE10A00E4BCE2 /* Window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Window.h; path = Classes/Window.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -132,6 +138,10 @@
FA3250E014BA87B800BF0781 /* Classes */ = {
isa = PBXGroup;
children = (
24E5CE5818F8417A006CC84A /* DownloadInfo.h */,
24E5CE5918F8417A006CC84A /* DownloadInfo.m */,
24E5CE5518F83217006CC84A /* DownloadDelegate.h */,
24E5CE5618F83217006CC84A /* DownloadDelegate.m */,
FA3250E114BA87DD00BF0781 /* Commands */,
FA3250BA14BA85E700BF0781 /* Constants.h */,
6F169DA818CC35FD005EDDF3 /* CallbackDelegate.h */,
Expand Down Expand Up @@ -320,9 +330,11 @@
6F169DAA18CC35FD005EDDF3 /* CallbackDelegate.m in Sources */,
FA3250D314BA860800BF0781 /* App.m in Sources */,
FA3250D514BA860800BF0781 /* Dock.m in Sources */,
24E5CE5718F83217006CC84A /* DownloadDelegate.m in Sources */,
FA3250D714BA860800BF0781 /* Growl.m in Sources */,
FA3250D914BA860800BF0781 /* Path.m in Sources */,
FA3250DB14BA860800BF0781 /* Sound.m in Sources */,
24E5CE5A18F8417A006CC84A /* DownloadInfo.m in Sources */,
FA3250C314BA85E700BF0781 /* ContentView.m in Sources */,
FA3250C514BA85E700BF0781 /* Utils.m in Sources */,
FA3250C714BA85E700BF0781 /* WebViewDelegate.m in Sources */,
Expand Down
3 changes: 3 additions & 0 deletions MacGap/Classes/ContentView.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
#import <Cocoa/Cocoa.h>
#import <WebKit/WebKit.h>
#import "DownloadDelegate.h"

@class WebViewDelegate;

@interface ContentView : NSView {
IBOutlet WebView* webView;
WebViewDelegate* delegate;
DownloadDelegate* downloadDelegate;
}

@property (retain) WebView* webView;
@property (retain) WebViewDelegate* delegate;
@property (retain) DownloadDelegate* downloadDelegate;
@property (strong) IBOutlet NSMenu *mainMenu;

@end
6 changes: 4 additions & 2 deletions MacGap/Classes/ContentView.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#import "WebViewDelegate.h"
#import "AppDelegate.h"
#import "JSEventHelper.h"
#import "DownloadDelegate.h"

@interface WebPreferences (WebPreferencesPrivate)
- (void)_setLocalStorageDatabasePath:(NSString *)path;
Expand All @@ -14,7 +15,7 @@ - (void) setOfflineWebApplicationCacheEnabled:(BOOL)offlineWebApplicationCacheEn

@implementation ContentView

@synthesize webView, delegate, mainMenu;
@synthesize webView, delegate, downloadDelegate, mainMenu;

- (void) awakeFromNib
{
Expand All @@ -39,10 +40,11 @@ - (void) awakeFromNib
[self.webView setApplicationNameForUserAgent: @"MacGap"];

self.delegate = [[WebViewDelegate alloc] initWithMenu:[NSApp mainMenu]];
self.downloadDelegate = [[DownloadDelegate alloc] init];
[self.webView setFrameLoadDelegate:self.delegate];
[self.webView setUIDelegate:self.delegate];
[self.webView setResourceLoadDelegate:self.delegate];
[self.webView setDownloadDelegate:self.delegate];
[self.webView setDownloadDelegate:self.downloadDelegate];
[self.webView setPolicyDelegate:self.delegate];
[self.webView setDrawsBackground:NO];
[self.webView setShouldCloseWithWindow:NO];
Expand Down
17 changes: 17 additions & 0 deletions MacGap/Classes/DownloadDelegate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// DownloadDelegate.h
// MacGap
//
// Created by Jack Zhuang on 4/11/2014.
// Copyright (c) 2014 SteedOS Inc. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface DownloadDelegate : NSObject {
NSString *suggestedFilename;

NSSavePanel *panel;
}

@end
83 changes: 83 additions & 0 deletions MacGap/Classes/DownloadDelegate.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
//
// DownloadDelegate.m
// MacGap
//
// Created by Jack Zhuang on 4/11/2014.
// Copyright (c) 2014 SteedOS Inc. All rights reserved.
//

#import "DownloadDelegate.h"
#import "DownloadInfo.h"


@implementation DownloadDelegate {
NSMapTable *downloads;
}

- (id)init
{
self = [super init];
if (self && NSClassFromString(@"NSProgress")) {
downloads = [NSMapTable weakToStrongObjectsMapTable];
}
return self;
}


- (void)download:(NSURLDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename
{
NSString *downloadDir = [NSSearchPathForDirectoriesInDomains(NSDownloadsDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *destinationFilename = [downloadDir stringByAppendingPathComponent:filename];
[download setDestination:destinationFilename allowOverwrite:NO];
}

-(void)download:(NSURLDownload *)download didCreateDestination:(NSString *)path
{
if (downloads) {
NSURL *downloadUrl = [NSURL fileURLWithPath:path];
DownloadInfo *info = [downloads objectForKey:download];
[info setFilename:path];

NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
NSProgressFileOperationKindDownloading,
NSProgressFileOperationKindKey,
nil];
NSProgress *progress = [NSProgress progressWithTotalUnitCount:0];
progress = [progress initWithParent:nil userInfo:userInfo];
[progress setKind:NSProgressKindFile];
[progress setUserInfoObject:downloadUrl forKey:NSProgressFileURLKey];
[progress publish];
[info setProgress:progress];
}
}

- (void)download:(NSURLDownload *)download didReceiveResponse:(NSURLResponse *)response
{
if (downloads) {
DownloadInfo *info = [[DownloadInfo alloc] init];
[info setResponse:response];
[downloads setObject:info forKey:download];
}
}

- (void)download:(NSURLDownload *)download didReceiveDataOfLength:(unsigned)length {
if (downloads) {
DownloadInfo *info = [downloads objectForKey:download];
long long expectedLength = [[info response] expectedContentLength];
int64_t completed = [[info progress] completedUnitCount];
[[info progress] setCompletedUnitCount:(completed + length)];
if (expectedLength != NSURLResponseUnknownLength) [[info progress] setTotalUnitCount:expectedLength];
}
}

- (void)downloadDidFinish:(NSURLDownload *)download {
if (downloads) {
DownloadInfo *info = [downloads objectForKey:download];
[[info progress] unpublish];
[[NSDistributedNotificationCenter defaultCenter] postNotificationName:@"com.apple.DownloadFileFinished" object:[info filename]];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great to see some use of our JSEventHelper's triggerEvent — I think there are actually several places in your code where it could be really handy to fire off some JS events.

[downloads removeObjectForKey:download];
}
}


@end
19 changes: 19 additions & 0 deletions MacGap/Classes/DownloadInfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//
// A wrapper class for storing all the information relevant to a particular download.
//
// Created by Jack Zhuang on 4/11/2014.
// Copyright (c) 2014 SteedOS Inc. All rights reserved.
//


#import <Foundation/Foundation.h>

@interface DownloadInfo : NSObject<NSCopying>

@property NSProgress *progress;
@property NSURLResponse *response;
@property NSString *filename;

- (id)copyWithZone:(NSZone *)zone;

@end
24 changes: 24 additions & 0 deletions MacGap/Classes/DownloadInfo.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// Created by Jack Zhuang on 4/11/2014.
// Copyright (c) 2014 SteedOS Inc. All rights reserved.
//


#import "DownloadInfo.h"

@implementation DownloadInfo

- (id)copyWithZone:(NSZone *)zone
{
DownloadInfo *copy = [[[self class] alloc] init];

if (copy) {
copy.progress = self.progress;
copy.response = self.response;
copy.filename = self.filename;
}

return copy;
}

@end
23 changes: 22 additions & 1 deletion MacGap/Classes/WebViewDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ - (NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary
switch (tag)
{
case WebMenuItemTagOpenLinkInNewWindow:
case WebMenuItemTagDownloadLinkToDisk:
//case WebMenuItemTagDownloadLinkToDisk:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to remove commented line.

case WebMenuItemTagCopyLinkToClipboard:
case WebMenuItemTagOpenImageInNewWindow:
case WebMenuItemTagDownloadImageToDisk:
Expand Down Expand Up @@ -196,4 +196,25 @@ + (BOOL) isKeyExcludedFromWebScript:(const char*)name
}


/*
* Download everything except HTML pages.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason this needs to be mandatory for all use-cases?

*/
- (void)webView:(WebView *)webView decidePolicyForMIMEType:(NSString *)type
request:(NSURLRequest *)request
frame:(WebFrame *)frame
decisionListener:(id < WebPolicyDecisionListener >)listener
{
NSLog (@"%@", type);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to remove NSLog.

if([type isEqualToString:@"text/html"])
{

[listener use];
}
else{
[listener download];
};
}



@end