diff options
36 files changed, 859 insertions, 78 deletions
diff --git a/build-mac/mailcore2.xcodeproj/project.pbxproj b/build-mac/mailcore2.xcodeproj/project.pbxproj index df155675..e127f4f2 100644 --- a/build-mac/mailcore2.xcodeproj/project.pbxproj +++ b/build-mac/mailcore2.xcodeproj/project.pbxproj @@ -633,6 +633,9 @@ C6EB310116B8E6E60091F4F1 /* NSObject+MCO.mm in Sources */ = {isa = PBXBuildFile; fileRef = C6EB310016B8E6E50091F4F1 /* NSObject+MCO.mm */; }; C6EB310216B8E7D60091F4F1 /* NSObject+MCO.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C6EB30FF16B8E6E50091F4F1 /* NSObject+MCO.h */; }; C6EB310316B8E7D80091F4F1 /* NSArray+MCO.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C6EB30FD16B8E50F0091F4F1 /* NSArray+MCO.h */; }; + C6ED6D1A17A1919500A4A14C /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C6ED6D1917A1919500A4A14C /* Security.framework */; }; + C6ED6D1B17A191B100A4A14C /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C64EA7B016A00BBB00778456 /* CoreServices.framework */; }; + C6ED6D1D17A191BF00A4A14C /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C6ED6D1C17A191BF00A4A14C /* Security.framework */; }; C6F5B9E216FEA1E800D9DABD /* MCOIMAPMessage.mm in Sources */ = {isa = PBXBuildFile; fileRef = C6F5B9E116FEA1E800D9DABD /* MCOIMAPMessage.mm */; }; C6F5B9E516FEA27500D9DABD /* MCOIMAPMessagePart.mm in Sources */ = {isa = PBXBuildFile; fileRef = C6F5B9E416FEA27500D9DABD /* MCOIMAPMessagePart.mm */; }; C6F5B9E816FEA28600D9DABD /* MCOIMAPMultipart.mm in Sources */ = {isa = PBXBuildFile; fileRef = C6F5B9E716FEA28600D9DABD /* MCOIMAPMultipart.mm */; }; @@ -681,6 +684,8 @@ C6F61FB21702886B0073032E /* MCORFC822.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C64BB26B16FD4C3B000DB34C /* MCORFC822.h */; }; C6F61FB51702AB340073032E /* MCOIMAPBaseOperation.mm in Sources */ = {isa = PBXBuildFile; fileRef = C6F61FB41702AB2F0073032E /* MCOIMAPBaseOperation.mm */; }; C6F61FB61702B5290073032E /* MCOIMAPBaseOperation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = C6F61FB31702AB2A0073032E /* MCOIMAPBaseOperation.h */; }; + C6F7B19F17A1C15200BE78BB /* MCCertificateUtils.cc in Sources */ = {isa = PBXBuildFile; fileRef = C6F7B19D17A1C15200BE78BB /* MCCertificateUtils.cc */; }; + C6F7B1A017A1C15200BE78BB /* MCCertificateUtils.cc in Sources */ = {isa = PBXBuildFile; fileRef = C6F7B19D17A1C15200BE78BB /* MCCertificateUtils.cc */; }; DA0F1C7B177C07B300F0D3B4 /* MCIMAPMessageRenderingOperation.cc in Sources */ = {isa = PBXBuildFile; fileRef = DA0F1C79177C07B300F0D3B4 /* MCIMAPMessageRenderingOperation.cc */; }; DA0F1C7C177C07B300F0D3B4 /* MCIMAPMessageRenderingOperation.cc in Sources */ = {isa = PBXBuildFile; fileRef = DA0F1C79177C07B300F0D3B4 /* MCIMAPMessageRenderingOperation.cc */; }; DA89896D178A47D200F6D90A /* MCOIMAPMessageRenderingOperation.mm in Sources */ = {isa = PBXBuildFile; fileRef = DA89896C178A47D200F6D90A /* MCOIMAPMessageRenderingOperation.mm */; }; @@ -1436,6 +1441,8 @@ C6EB30FD16B8E50F0091F4F1 /* NSArray+MCO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+MCO.h"; sourceTree = "<group>"; }; C6EB30FF16B8E6E50091F4F1 /* NSObject+MCO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+MCO.h"; sourceTree = "<group>"; }; C6EB310016B8E6E50091F4F1 /* NSObject+MCO.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSObject+MCO.mm"; sourceTree = "<group>"; }; + C6ED6D1917A1919500A4A14C /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; + C6ED6D1C17A191BF00A4A14C /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/System/Library/Frameworks/Security.framework; sourceTree = DEVELOPER_DIR; }; C6F5B9E016FEA1E800D9DABD /* MCOIMAPMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCOIMAPMessage.h; sourceTree = "<group>"; }; C6F5B9E116FEA1E800D9DABD /* MCOIMAPMessage.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCOIMAPMessage.mm; sourceTree = "<group>"; }; C6F5B9E316FEA27500D9DABD /* MCOIMAPMessagePart.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCOIMAPMessagePart.h; sourceTree = "<group>"; }; @@ -1479,6 +1486,8 @@ C6F61F9E17016EA00073032E /* MCOIMAPFolderInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MCOIMAPFolderInfo.m; sourceTree = "<group>"; }; C6F61FB31702AB2A0073032E /* MCOIMAPBaseOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCOIMAPBaseOperation.h; sourceTree = "<group>"; }; C6F61FB41702AB2F0073032E /* MCOIMAPBaseOperation.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCOIMAPBaseOperation.mm; sourceTree = "<group>"; }; + C6F7B19D17A1C15200BE78BB /* MCCertificateUtils.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCCertificateUtils.cc; sourceTree = "<group>"; }; + C6F7B19E17A1C15200BE78BB /* MCCertificateUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCCertificateUtils.h; sourceTree = "<group>"; }; DA0F1C79177C07B300F0D3B4 /* MCIMAPMessageRenderingOperation.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MCIMAPMessageRenderingOperation.cc; sourceTree = "<group>"; }; DA0F1C7A177C07B300F0D3B4 /* MCIMAPMessageRenderingOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCIMAPMessageRenderingOperation.h; sourceTree = "<group>"; }; DA89896B178A47D200F6D90A /* MCOIMAPMessageRenderingOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCOIMAPMessageRenderingOperation.h; sourceTree = "<group>"; }; @@ -1514,6 +1523,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + C6ED6D1D17A191BF00A4A14C /* Security.framework in Frameworks */, C6A81BB41706891B00882C15 /* CFNetwork.framework in Frameworks */, C6A81BB2170685A700882C15 /* libMailCore-ios.a in Frameworks */, C6A81B931706840C00882C15 /* UIKit.framework in Frameworks */, @@ -1533,6 +1543,8 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + C6ED6D1B17A191B100A4A14C /* CoreServices.framework in Frameworks */, + C6ED6D1A17A1919500A4A14C /* Security.framework in Frameworks */, C6BD28A3170BD84F00A91AC1 /* libMailCore.a in Frameworks */, C6BD288F170BD71100A91AC1 /* Cocoa.framework in Frameworks */, ); @@ -1789,6 +1801,7 @@ C64EA691169E847800778456 /* core */ = { isa = PBXGroup; children = ( + C6F7B19C17A1C11F00BE78BB /* security */, C6E665A91796500B0063F2CF /* zip */, C64EA692169E847800778456 /* abstract */, C64EA6A1169E847800778456 /* basetypes */, @@ -1964,6 +1977,8 @@ C64EA78E169F259200778456 /* Frameworks */ = { isa = PBXGroup; children = ( + C6ED6D1C17A191BF00A4A14C /* Security.framework */, + C6ED6D1917A1919500A4A14C /* Security.framework */, C6A81BB31706891B00882C15 /* CFNetwork.framework */, C64EA7B016A00BBB00778456 /* CoreServices.framework */, C64EA78F169F259200778456 /* Foundation.framework */, @@ -2127,6 +2142,15 @@ path = smtp; sourceTree = "<group>"; }; + C6F7B19C17A1C11F00BE78BB /* security */ = { + isa = PBXGroup; + children = ( + C6F7B19D17A1C15200BE78BB /* MCCertificateUtils.cc */, + C6F7B19E17A1C15200BE78BB /* MCCertificateUtils.h */, + ); + path = security; + sourceTree = "<group>"; + }; F8EA941316BAED500011AC6F /* imap */ = { isa = PBXGroup; children = ( @@ -2435,6 +2459,7 @@ C64EA744169E847800778456 /* MCMultipart.cc in Sources */, C64EA781169E89F600778456 /* MCSMTPSession.cc in Sources */, C64EA784169F24E400778456 /* MCSMTPAsyncSession.cc in Sources */, + C6F7B19F17A1C15200BE78BB /* MCCertificateUtils.cc in Sources */, C64EA79E169F29A700778456 /* MCSMTPSendWithDataOperation.cc in Sources */, C64EA7DA16A1386600778456 /* MCSMTPOperation.cc in Sources */, C64EA7EA16A154B300778456 /* MCSMTPCheckAccountOperation.cc in Sources */, @@ -2624,6 +2649,7 @@ C6BA2BBD1705F4E6003F0E9E /* MCMultipart.cc in Sources */, C6BA2BBE1705F4E6003F0E9E /* MCSMTPSession.cc in Sources */, C6BA2BBF1705F4E6003F0E9E /* MCSMTPAsyncSession.cc in Sources */, + C6F7B1A017A1C15200BE78BB /* MCCertificateUtils.cc in Sources */, C6BA2BC01705F4E6003F0E9E /* MCSMTPSendWithDataOperation.cc in Sources */, C6BA2BC11705F4E6003F0E9E /* MCSMTPOperation.cc in Sources */, C6BA2BC21705F4E6003F0E9E /* MCSMTPCheckAccountOperation.cc in Sources */, diff --git a/example/ios/iOS UI Test/iOS UI Test.xcodeproj/project.pbxproj b/example/ios/iOS UI Test/iOS UI Test.xcodeproj/project.pbxproj index eec98dc0..da41f157 100644 --- a/example/ios/iOS UI Test/iOS UI Test.xcodeproj/project.pbxproj +++ b/example/ios/iOS UI Test/iOS UI Test.xcodeproj/project.pbxproj @@ -24,9 +24,7 @@ AB9EAE3617036FD700D750C7 /* SettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AB9EAE3417036FD600D750C7 /* SettingsViewController.m */; }; AB9EAE3717036FD700D750C7 /* SettingsViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = AB9EAE3517036FD700D750C7 /* SettingsViewController.xib */; }; AB9EAE40170374D900D750C7 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB9EAE3F170374D900D750C7 /* Security.framework */; }; - ABE40269173F0282007F1FB3 /* MCOMessageViewScript.js in Resources */ = {isa = PBXBuildFile; fileRef = ABE40267173F0151007F1FB3 /* MCOMessageViewScript.js */; }; ABE4026B173F3FCE007F1FB3 /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ABE4026A173F3FCE007F1FB3 /* ImageIO.framework */; }; - B12AAA3417322654003551C7 /* MCOMessageView.mm in Sources */ = {isa = PBXBuildFile; fileRef = B12AAA3017322654003551C7 /* MCOMessageView.mm */; }; B12AAA3517322654003551C7 /* MCTMsgViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = B12AAA3217322654003551C7 /* MCTMsgViewController.mm */; }; C6D7194D178BB8B4008ED15F /* GTMHTTPFetcher.m in Sources */ = {isa = PBXBuildFile; fileRef = C6D71939178BA812008ED15F /* GTMHTTPFetcher.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; C6D7194E178BB8B4008ED15F /* GTMHTTPFetchHistory.m in Sources */ = {isa = PBXBuildFile; fileRef = C6D7193B178BA812008ED15F /* GTMHTTPFetchHistory.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; @@ -35,6 +33,8 @@ C6D71951178BB8B4008ED15F /* GTMOAuth2ViewControllerTouch.m in Sources */ = {isa = PBXBuildFile; fileRef = C6D71947178BA812008ED15F /* GTMOAuth2ViewControllerTouch.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; C6D71952178BB8B4008ED15F /* GTMOAuth2ViewTouch.xib in Resources */ = {isa = PBXBuildFile; fileRef = C6D71948178BA812008ED15F /* GTMOAuth2ViewTouch.xib */; }; C6D71954178BB91E008ED15F /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C6D71953178BB91E008ED15F /* SystemConfiguration.framework */; }; + C6ED6D2917A19F2700A4A14C /* MCOCIDURLProtocol.mm in Sources */ = {isa = PBXBuildFile; fileRef = C6ED6D2817A19F1500A4A14C /* MCOCIDURLProtocol.mm */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + C6ED6D2A17A19F2B00A4A14C /* MCOMessageView.mm in Sources */ = {isa = PBXBuildFile; fileRef = C6ED6D2517A19EF800A4A14C /* MCOMessageView.mm */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; DA9AD477179331A600743873 /* MCTTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = DA9AD476179331A600743873 /* MCTTableViewCell.m */; }; /* End PBXBuildFile section */ @@ -109,10 +109,7 @@ AB9EAE3417036FD600D750C7 /* SettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsViewController.m; sourceTree = "<group>"; }; AB9EAE3517036FD700D750C7 /* SettingsViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = SettingsViewController.xib; sourceTree = "<group>"; }; AB9EAE3F170374D900D750C7 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; - ABE40267173F0151007F1FB3 /* MCOMessageViewScript.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = MCOMessageViewScript.js; sourceTree = "<group>"; }; ABE4026A173F3FCE007F1FB3 /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = System/Library/Frameworks/ImageIO.framework; sourceTree = SDKROOT; }; - B12AAA2F17322654003551C7 /* MCOMessageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCOMessageView.h; sourceTree = "<group>"; }; - B12AAA3017322654003551C7 /* MCOMessageView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCOMessageView.mm; sourceTree = "<group>"; }; B12AAA3117322654003551C7 /* MCTMsgViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCTMsgViewController.h; sourceTree = "<group>"; }; B12AAA3217322654003551C7 /* MCTMsgViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCTMsgViewController.mm; sourceTree = "<group>"; }; C6D71938178BA812008ED15F /* GTMHTTPFetcher.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GTMHTTPFetcher.h; sourceTree = "<group>"; }; @@ -127,6 +124,10 @@ C6D71947178BA812008ED15F /* GTMOAuth2ViewControllerTouch.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GTMOAuth2ViewControllerTouch.m; sourceTree = "<group>"; }; C6D71948178BA812008ED15F /* GTMOAuth2ViewTouch.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GTMOAuth2ViewTouch.xib; sourceTree = "<group>"; }; C6D71953178BB91E008ED15F /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; + C6ED6D2417A19EF800A4A14C /* MCOMessageView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCOMessageView.h; sourceTree = "<group>"; }; + C6ED6D2517A19EF800A4A14C /* MCOMessageView.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MCOMessageView.mm; sourceTree = "<group>"; }; + C6ED6D2717A19F1500A4A14C /* MCOCIDURLProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCOCIDURLProtocol.h; sourceTree = "<group>"; }; + C6ED6D2817A19F1500A4A14C /* MCOCIDURLProtocol.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MCOCIDURLProtocol.mm; sourceTree = "<group>"; }; DA9AD475179331A600743873 /* MCTTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCTTableViewCell.h; sourceTree = "<group>"; }; DA9AD476179331A600743873 /* MCTTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MCTTableViewCell.m; sourceTree = "<group>"; }; /* End PBXFileReference section */ @@ -207,7 +208,6 @@ AB9EAE0B170368F000D750C7 /* iOS UI Test */ = { isa = PBXGroup; children = ( - C6D71936178BA812008ED15F /* gtm-oauth2 */, AB7BA4321713898B00104953 /* mailcore2.xcodeproj */, AB9EAE11170368F000D750C7 /* main.mm */, AB9EAE14170368F000D750C7 /* AppDelegate.h */, @@ -215,14 +215,14 @@ AB9EAE1D170368F000D750C7 /* MainStoryboard.storyboard */, AB9EAE20170368F000D750C7 /* MasterViewController.h */, AB9EAE21170368F000D750C7 /* MasterViewController.m */, - B12AAA2F17322654003551C7 /* MCOMessageView.h */, - B12AAA3017322654003551C7 /* MCOMessageView.mm */, - ABE40267173F0151007F1FB3 /* MCOMessageViewScript.js */, B12AAA3117322654003551C7 /* MCTMsgViewController.h */, B12AAA3217322654003551C7 /* MCTMsgViewController.mm */, AB9EAE3317036FD600D750C7 /* SettingsViewController.h */, AB9EAE3417036FD600D750C7 /* SettingsViewController.m */, AB9EAE3517036FD700D750C7 /* SettingsViewController.xib */, + C6D71936178BA812008ED15F /* gtm-oauth2 */, + C6ED6D2617A19F1500A4A14C /* common */, + C6ED6D2317A19EF800A4A14C /* ios */, AB9EAE0C170368F000D750C7 /* Supporting Files */, AB665BC917134336007F2151 /* common */, DA9AD475179331A600743873 /* MCTTableViewCell.h */, @@ -287,6 +287,26 @@ path = Touch; sourceTree = "<group>"; }; + C6ED6D2317A19EF800A4A14C /* ios */ = { + isa = PBXGroup; + children = ( + C6ED6D2417A19EF800A4A14C /* MCOMessageView.h */, + C6ED6D2517A19EF800A4A14C /* MCOMessageView.mm */, + ); + name = ios; + path = ../../../../src/ui/ios; + sourceTree = "<group>"; + }; + C6ED6D2617A19F1500A4A14C /* common */ = { + isa = PBXGroup; + children = ( + C6ED6D2717A19F1500A4A14C /* MCOCIDURLProtocol.h */, + C6ED6D2817A19F1500A4A14C /* MCOCIDURLProtocol.mm */, + ); + name = common; + path = ../../../../src/ui/common; + sourceTree = "<group>"; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -384,7 +404,6 @@ buildActionMask = 2147483647; files = ( C6D71952178BB8B4008ED15F /* GTMOAuth2ViewTouch.xib in Resources */, - ABE40269173F0282007F1FB3 /* MCOMessageViewScript.js in Resources */, AB9EAE10170368F000D750C7 /* InfoPlist.strings in Resources */, AB9EAE18170368F000D750C7 /* Default.png in Resources */, AB9EAE1A170368F000D750C7 /* Default@2x.png in Resources */, @@ -407,11 +426,12 @@ AB9EAE22170368F000D750C7 /* MasterViewController.m in Sources */, AB9EAE3617036FD700D750C7 /* SettingsViewController.m in Sources */, C6D7194D178BB8B4008ED15F /* GTMHTTPFetcher.m in Sources */, + C6ED6D2917A19F2700A4A14C /* MCOCIDURLProtocol.mm in Sources */, C6D71951178BB8B4008ED15F /* GTMOAuth2ViewControllerTouch.m in Sources */, + C6ED6D2A17A19F2B00A4A14C /* MCOMessageView.mm in Sources */, AB665BCD17134336007F2151 /* FXKeychain.m in Sources */, C6D71950178BB8B4008ED15F /* GTMOAuth2SignIn.m in Sources */, C6D7194F178BB8B4008ED15F /* GTMOAuth2Authentication.m in Sources */, - B12AAA3417322654003551C7 /* MCOMessageView.mm in Sources */, B12AAA3517322654003551C7 /* MCTMsgViewController.mm in Sources */, DA9AD477179331A600743873 /* MCTTableViewCell.m in Sources */, ); diff --git a/example/mac/macExample/macExample.xcodeproj/project.pbxproj b/example/mac/macExample/macExample.xcodeproj/project.pbxproj index c03d6be7..89dcf3c0 100644 --- a/example/mac/macExample/macExample.xcodeproj/project.pbxproj +++ b/example/mac/macExample/macExample.xcodeproj/project.pbxproj @@ -10,7 +10,6 @@ AB666C5917484E6200545290 /* FXKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = AB666C5817484E6200545290 /* FXKeychain.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; AB666C5B1748558000545290 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AB666C5A1748558000545290 /* Security.framework */; }; C64FF38416AF97F400F8C162 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = C64FF38316AF97F400F8C162 /* main.mm */; }; - C6BD2873170BC5C500A91AC1 /* MCOCIDURLProtocol.mm in Sources */ = {isa = PBXBuildFile; fileRef = C6BD2870170BC5C500A91AC1 /* MCOCIDURLProtocol.mm */; }; C6BD2874170BC5C500A91AC1 /* MCOMessageView.mm in Sources */ = {isa = PBXBuildFile; fileRef = C6BD2872170BC5C500A91AC1 /* MCOMessageView.mm */; }; C6BD28B4170BDFE500A91AC1 /* MailCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C6BD28B3170BDFE500A91AC1 /* MailCore.framework */; }; C6D42BB616ABB39A002BB4F9 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C6D42BB516ABB39A002BB4F9 /* Cocoa.framework */; }; @@ -27,6 +26,7 @@ C6D71932178B7D6E008ED15F /* GTMHTTPFetchHistory.m in Sources */ = {isa = PBXBuildFile; fileRef = C6D71921178B7D55008ED15F /* GTMHTTPFetchHistory.m */; }; C6D71933178B7D72008ED15F /* GTMOAuth2Window.xib in Resources */ = {isa = PBXBuildFile; fileRef = C6D71928178B7D55008ED15F /* GTMOAuth2Window.xib */; }; C6D71934178B7D72008ED15F /* GTMOAuth2WindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = C6D7192A178B7D55008ED15F /* GTMOAuth2WindowController.m */; }; + C6ED6CE817A0D06200A4A14C /* MCOCIDURLProtocol.mm in Sources */ = {isa = PBXBuildFile; fileRef = C6ED6CE717A0D05300A4A14C /* MCOCIDURLProtocol.mm */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -92,8 +92,6 @@ AB666C5817484E6200545290 /* FXKeychain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FXKeychain.m; path = ../../../common/FXKeychain.m; sourceTree = "<group>"; }; AB666C5A1748558000545290 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; C64FF38316AF97F400F8C162 /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = "<group>"; }; - C6BD286F170BC5C500A91AC1 /* MCOCIDURLProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCOCIDURLProtocol.h; sourceTree = "<group>"; }; - C6BD2870170BC5C500A91AC1 /* MCOCIDURLProtocol.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCOCIDURLProtocol.mm; sourceTree = "<group>"; }; C6BD2871170BC5C500A91AC1 /* MCOMessageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MCOMessageView.h; sourceTree = "<group>"; }; C6BD2872170BC5C500A91AC1 /* MCOMessageView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MCOMessageView.mm; sourceTree = "<group>"; }; C6BD2877170BC8ED00A91AC1 /* mailcore2.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = mailcore2.xcodeproj; path = "../../../build-mac/mailcore2.xcodeproj"; sourceTree = "<group>"; }; @@ -123,6 +121,8 @@ C6D71928178B7D55008ED15F /* GTMOAuth2Window.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GTMOAuth2Window.xib; sourceTree = "<group>"; }; C6D71929178B7D55008ED15F /* GTMOAuth2WindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GTMOAuth2WindowController.h; sourceTree = "<group>"; }; C6D7192A178B7D55008ED15F /* GTMOAuth2WindowController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = GTMOAuth2WindowController.m; sourceTree = "<group>"; }; + C6ED6CE617A0D05300A4A14C /* MCOCIDURLProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCOCIDURLProtocol.h; sourceTree = "<group>"; }; + C6ED6CE717A0D05300A4A14C /* MCOCIDURLProtocol.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MCOCIDURLProtocol.mm; sourceTree = "<group>"; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -153,6 +153,7 @@ C6BD286D170BC5C500A91AC1 /* ui */ = { isa = PBXGroup; children = ( + C6ED6CE517A0D05300A4A14C /* common */, C6BD286E170BC5C500A91AC1 /* mac */, ); name = ui; @@ -162,8 +163,6 @@ C6BD286E170BC5C500A91AC1 /* mac */ = { isa = PBXGroup; children = ( - C6BD286F170BC5C500A91AC1 /* MCOCIDURLProtocol.h */, - C6BD2870170BC5C500A91AC1 /* MCOCIDURLProtocol.mm */, C6BD2871170BC5C500A91AC1 /* MCOMessageView.h */, C6BD2872170BC5C500A91AC1 /* MCOMessageView.mm */, ); @@ -308,6 +307,15 @@ path = Mac; sourceTree = "<group>"; }; + C6ED6CE517A0D05300A4A14C /* common */ = { + isa = PBXGroup; + children = ( + C6ED6CE617A0D05300A4A14C /* MCOCIDURLProtocol.h */, + C6ED6CE717A0D05300A4A14C /* MCOCIDURLProtocol.mm */, + ); + path = common; + sourceTree = "<group>"; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -417,6 +425,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + C6ED6CE817A0D06200A4A14C /* MCOCIDURLProtocol.mm in Sources */, C6D42BC916ABB39A002BB4F9 /* AppDelegate.m in Sources */, C6D71930178B7D67008ED15F /* GTMOAuth2SignIn.m in Sources */, C6D42BE916ACF711002BB4F9 /* MCTMsgListViewController.m in Sources */, @@ -424,7 +433,6 @@ C6D71931178B7D6C008ED15F /* GTMHTTPFetcher.m in Sources */, C6D71934178B7D72008ED15F /* GTMOAuth2WindowController.m in Sources */, C64FF38416AF97F400F8C162 /* main.mm in Sources */, - C6BD2873170BC5C500A91AC1 /* MCOCIDURLProtocol.mm in Sources */, C6BD2874170BC5C500A91AC1 /* MCOMessageView.mm in Sources */, AB666C5917484E6200545290 /* FXKeychain.m in Sources */, C6D7192F178B7D65008ED15F /* GTMOAuth2Authentication.m in Sources */, diff --git a/scripts/prepare-libetpan-ios.sh b/scripts/prepare-libetpan-ios.sh index 4e4f9d6e..beb8b174 100755 --- a/scripts/prepare-libetpan-ios.sh +++ b/scripts/prepare-libetpan-ios.sh @@ -2,7 +2,7 @@ sdkversion=6.1 url="https://github.com/dinhviethoa/libetpan.git" -rev=3c99ce26d751c168c4e67813e1bedc6a6c4d1c87 +rev=cff50f652938fa0390ef421d311b4e86a36d246f pushd `dirname $0` > /dev/null scriptpath=`pwd` diff --git a/scripts/prepare-libetpan-macos.sh b/scripts/prepare-libetpan-macos.sh index b932cb0b..d13426d6 100755 --- a/scripts/prepare-libetpan-macos.sh +++ b/scripts/prepare-libetpan-macos.sh @@ -1,7 +1,7 @@ #!/bin/sh url="https://github.com/dinhviethoa/libetpan.git" -rev=3c99ce26d751c168c4e67813e1bedc6a6c4d1c87 +rev=cff50f652938fa0390ef421d311b4e86a36d246f pushd `dirname $0` > /dev/null scriptpath=`pwd` diff --git a/src/async/imap/MCIMAPOperation.cc b/src/async/imap/MCIMAPOperation.cc index a983fe55..35eedd6c 100644 --- a/src/async/imap/MCIMAPOperation.cc +++ b/src/async/imap/MCIMAPOperation.cc @@ -94,8 +94,10 @@ void IMAPOperation::bodyProgress(IMAPSession * session, unsigned int current, un void IMAPOperation::bodyProgressOnMainThread(void * ctx) { - if (isCancelled()) + if (isCancelled()) { + release(); return; + } struct progressContext * context = (struct progressContext *) ctx; if (mImapCallback != NULL) { @@ -107,10 +109,8 @@ void IMAPOperation::bodyProgressOnMainThread(void * ctx) void IMAPOperation::itemsProgress(IMAPSession * session, unsigned int current, unsigned int maximum) { - if (isCancelled()) { - release(); + if (isCancelled()) return; - } struct progressContext * context = (struct progressContext *) calloc(sizeof(* context), 1); context->current = current; diff --git a/src/async/pop/MCPOPOperation.cc b/src/async/pop/MCPOPOperation.cc index 7fb279d6..76ecdb82 100644 --- a/src/async/pop/MCPOPOperation.cc +++ b/src/async/pop/MCPOPOperation.cc @@ -73,14 +73,22 @@ void POPOperation::bodyProgress(POPSession * session, unsigned int current, unsi struct progressContext * context = (struct progressContext *) calloc(sizeof(* context), 1); context->current = current; context->maximum = maximum; + + retain(); performMethodOnMainThread((Object::Method) &POPOperation::bodyProgressOnMainThread, context); } void POPOperation::bodyProgressOnMainThread(void * ctx) { + if (isCancelled()) { + release(); + return; + } + struct progressContext * context = (struct progressContext *) ctx; if (mPopCallback != NULL) { mPopCallback->bodyProgress(this, context->current, context->maximum); } free(context); + release(); } diff --git a/src/async/smtp/MCSMTPOperation.cc b/src/async/smtp/MCSMTPOperation.cc index e8211a24..0661ce9f 100644 --- a/src/async/smtp/MCSMTPOperation.cc +++ b/src/async/smtp/MCSMTPOperation.cc @@ -71,14 +71,22 @@ void SMTPOperation::bodyProgress(SMTPSession * session, unsigned int current, un struct progressContext * context = (struct progressContext *) calloc(sizeof(* context), 1); context->current = current; context->maximum = maximum; + + retain(); performMethodOnMainThread((Object::Method) &SMTPOperation::bodyProgressOnMainThread, context); } void SMTPOperation::bodyProgressOnMainThread(void * ctx) { + if (isCancelled()) { + release(); + return; + } + struct progressContext * context = (struct progressContext *) ctx; if (mSmtpCallback != NULL) { mSmtpCallback->bodyProgress(this, context->current, context->maximum); } free(context); + release(); } diff --git a/src/core/basetypes/MCObject.cc b/src/core/basetypes/MCObject.cc index 235738cd..527b0c71 100644 --- a/src/core/basetypes/MCObject.cc +++ b/src/core/basetypes/MCObject.cc @@ -66,7 +66,9 @@ void Object::release() pthread_mutex_unlock(&mLock); if (shouldRelease && !zombieEnabled) { - //MCLog("dealloc %s", className()->description()->UTF8Characters()); + //int status; + //char * unmangled = abi::__cxa_demangle(typeid(* this).name(), NULL, NULL, &status); + //MCLog("dealloc %p %s", this, unmangled); delete this; } } diff --git a/src/core/imap/MCIMAPSession.cc b/src/core/imap/MCIMAPSession.cc index 35c5e7bd..e2fb4e1d 100644 --- a/src/core/imap/MCIMAPSession.cc +++ b/src/core/imap/MCIMAPSession.cc @@ -21,6 +21,7 @@ #include "MCUtils.h" #include "MCHTMLRendererIMAPDataCallback.h" #include "MCHTMLBodyRendererTemplateCallback.h" +#include "MCCertificateUtils.h" using namespace mailcore; @@ -468,7 +469,6 @@ bool IMAPSession::isVoIPEnabled() return mVoIPEnabled; } - void IMAPSession::setDelimiter(char delimiter) { mDelimiter = delimiter; @@ -487,8 +487,7 @@ static bool hasError(int errorCode) bool IMAPSession::checkCertificate() { - //TODO check certificate - return true; + return mailcore::checkCertificate(mImap->imap_stream, hostname()); } void IMAPSession::body_progress(size_t current, size_t maximum, void * context) diff --git a/src/core/pop/MCPOPSession.cc b/src/core/pop/MCPOPSession.cc index 42a8d585..393ec516 100644 --- a/src/core/pop/MCPOPSession.cc +++ b/src/core/pop/MCPOPSession.cc @@ -7,6 +7,7 @@ #include "MCPOPProgressCallback.h" #include "MCMessageHeader.h" #include "MCConnectionLoggerUtils.h" +#include "MCCertificateUtils.h" using namespace mailcore; @@ -129,8 +130,7 @@ bool POPSession::isCheckCertificateEnabled() bool POPSession::checkCertificate() { - //TODO check certificate - return true; + return mailcore::checkCertificate(mPop->pop3_stream, hostname()); } void POPSession::bodyProgress(unsigned int current, unsigned int maximum) diff --git a/src/core/security/MCCertificateUtils.cc b/src/core/security/MCCertificateUtils.cc new file mode 100644 index 00000000..f8f25f70 --- /dev/null +++ b/src/core/security/MCCertificateUtils.cc @@ -0,0 +1,66 @@ +// +// MCCertificateUtils.cc +// mailcore2 +// +// Created by DINH Viêt Hoà on 7/25/13. +// Copyright (c) 2013 MailCore. All rights reserved. +// + +#include "MCCertificateUtils.h" + +#if __APPLE__ +#include <CoreFoundation/CoreFoundation.h> +#include <Security/Security.h> +#endif + +#include "MCLog.h" + +bool mailcore::checkCertificate(mailstream * stream, String * hostname) +{ +#if __APPLE__ + bool result = false; + CFStringRef hostnameCFString = CFStringCreateWithCharacters(NULL, (const UniChar *) hostname->unicodeCharacters(), + hostname->length()); + SecPolicyRef policy = SecPolicyCreateSSL(true, hostnameCFString); + + CFMutableArrayRef certificates; + SecTrustRef trust; + certificates = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); + + carray * cCerts = mailstream_get_certificate_chain(stream); + for(unsigned int i = 0 ; i < carray_count(cCerts) ; i ++) { + MMAPString * str; + str = (MMAPString *) carray_get(cCerts, i); + CFDataRef data = CFDataCreate(NULL, (const UInt8 *) str->str, (CFIndex) str->len); + SecCertificateRef cert = SecCertificateCreateWithData(NULL, data); + CFArrayAppendValue(certificates, cert); + CFRelease(data); + + OSStatus status = SecTrustCreateWithCertificates(certificates, policy, &trust); + SecTrustResultType trustResult; + status = SecTrustEvaluate(trust, &trustResult); + switch (trustResult) { + case kSecTrustResultUnspecified: + case kSecTrustResultProceed: + // certificate chain is ok + result = true; + break; + + default: + // certificate chain is invalid + break; + } + } + + CFRelease(trust); + CFRelease(certificates); + CFRelease(policy); + CFRelease(hostnameCFString); + + return result; +#else + //TODO check certificate + // for other platforms too. + return true; +#endif +} diff --git a/src/core/security/MCCertificateUtils.h b/src/core/security/MCCertificateUtils.h new file mode 100644 index 00000000..0fcd9749 --- /dev/null +++ b/src/core/security/MCCertificateUtils.h @@ -0,0 +1,21 @@ +// +// MCCertificateUtils.h +// mailcore2 +// +// Created by DINH Viêt Hoà on 7/25/13. +// Copyright (c) 2013 MailCore. All rights reserved. +// + +#ifndef __MAILCORE_MCCERTIFICATEUTILS_H_ +#define __MAILCORE_MCCERTIFICATEUTILS_H_ + +#include <libetpan/libetpan.h> +#include <MailCore/MCString.h> + +namespace mailcore { + + bool checkCertificate(mailstream * stream, String * hostname); + +} + +#endif diff --git a/src/core/smtp/MCSMTPSession.cc b/src/core/smtp/MCSMTPSession.cc index cc2555f4..4677e2d6 100644 --- a/src/core/smtp/MCSMTPSession.cc +++ b/src/core/smtp/MCSMTPSession.cc @@ -9,6 +9,7 @@ #include "MCMessageHeader.h" #include "MCSMTPProgressCallback.h" #include "MCConnectionLoggerUtils.h" +#include "MCCertificateUtils.h" using namespace mailcore; @@ -146,8 +147,7 @@ bool SMTPSession::isCheckCertificateEnabled() bool SMTPSession::checkCertificate() { - //TODO check certificate - return true; + return mailcore::checkCertificate(mSmtp->stream, hostname()); } void SMTPSession::setUseHeloIPEnabled(bool enabled) diff --git a/src/objc/imap/MCOIMAPAppendMessageOperation.mm b/src/objc/imap/MCOIMAPAppendMessageOperation.mm index c281b925..72fb0343 100644 --- a/src/objc/imap/MCOIMAPAppendMessageOperation.mm +++ b/src/objc/imap/MCOIMAPAppendMessageOperation.mm @@ -42,19 +42,29 @@ typedef void (^CompletionType)(NSError *error, uint32_t createdUID); [super dealloc]; } -- (void)start:(void (^)(NSError *error, uint32_t createdUID))completionBlock { +- (void) start:(void (^)(NSError *error, uint32_t createdUID))completionBlock +{ _completionBlock = [completionBlock copy]; [self start]; } -- (void)operationCompleted { +- (void) cancel +{ + [_completionBlock release]; + _completionBlock = nil; + [super cancel]; +} + +- (void) operationCompleted +{ if (_completionBlock == NULL) return; nativeType *op = MCO_NATIVE_INSTANCE; if (op->error() == mailcore::ErrorNone) { _completionBlock(nil, op->createdUID()); - } else { + } + else { _completionBlock([NSError mco_errorWithErrorCode:op->error()], 0); } [_completionBlock release]; diff --git a/src/objc/imap/MCOIMAPCapabilityOperation.mm b/src/objc/imap/MCOIMAPCapabilityOperation.mm index 42952378..75f28610 100644 --- a/src/objc/imap/MCOIMAPCapabilityOperation.mm +++ b/src/objc/imap/MCOIMAPCapabilityOperation.mm @@ -38,12 +38,21 @@ typedef void (^CompletionType)(NSError *error, MCOIndexSet * capabilities); [super dealloc]; } -- (void)start:(void (^)(NSError *error, MCOIndexSet * capabilities))completionBlock { +- (void) start:(void (^)(NSError *error, MCOIndexSet * capabilities))completionBlock +{ _completionBlock = [completionBlock copy]; [self start]; } -- (void)operationCompleted { +- (void) cancel +{ + [_completionBlock release]; + _completionBlock = nil; + [super cancel]; +} + +- (void) operationCompleted +{ if (_completionBlock == NULL) return; diff --git a/src/objc/imap/MCOIMAPCopyMessagesOperation.mm b/src/objc/imap/MCOIMAPCopyMessagesOperation.mm index d14bcc84..eeee2e4a 100644 --- a/src/objc/imap/MCOIMAPCopyMessagesOperation.mm +++ b/src/objc/imap/MCOIMAPCopyMessagesOperation.mm @@ -39,19 +39,29 @@ typedef void (^CompletionType)(NSError *error, MCOIndexSet * destUids); [super dealloc]; } -- (void)start:(void (^)(NSError *error, MCOIndexSet * destUids))completionBlock { +- (void) start:(void (^)(NSError *error, MCOIndexSet * destUids))completionBlock +{ _completionBlock = [completionBlock copy]; [self start]; } -- (void)operationCompleted { +- (void) cancel +{ + [_completionBlock release]; + _completionBlock = nil; + [super cancel]; +} + +- (void) operationCompleted +{ if (_completionBlock == NULL) return; nativeType *op = MCO_NATIVE_INSTANCE; if (op->error() == mailcore::ErrorNone) { _completionBlock(nil, MCO_TO_OBJC(op->destUids())); - } else { + } + else { _completionBlock([NSError mco_errorWithErrorCode:op->error()], 0); } [_completionBlock release]; diff --git a/src/objc/imap/MCOIMAPFetchContentOperation.mm b/src/objc/imap/MCOIMAPFetchContentOperation.mm index d5d4757d..14867548 100644 --- a/src/objc/imap/MCOIMAPFetchContentOperation.mm +++ b/src/objc/imap/MCOIMAPFetchContentOperation.mm @@ -42,12 +42,20 @@ typedef void (^CompletionType)(NSError *error, NSData * data); [super dealloc]; } -- (void)start:(void (^)(NSError *error, NSData * data))completionBlock { +- (void) start:(void (^)(NSError *error, NSData * data))completionBlock { _completionBlock = [completionBlock copy]; [self start]; } -- (void)operationCompleted { +- (void) cancel +{ + [_completionBlock release]; + _completionBlock = nil; + [super cancel]; +} + +- (void) operationCompleted +{ if (_completionBlock == NULL) return; diff --git a/src/objc/imap/MCOIMAPFetchFoldersOperation.mm b/src/objc/imap/MCOIMAPFetchFoldersOperation.mm index 02b7d880..facccca3 100644 --- a/src/objc/imap/MCOIMAPFetchFoldersOperation.mm +++ b/src/objc/imap/MCOIMAPFetchFoldersOperation.mm @@ -43,19 +43,29 @@ typedef void (^CompletionType)(NSError *error, NSArray *folder); [super dealloc]; } -- (void)start:(void (^)(NSError *error, NSArray * /* MCOIMAPFolder */ folders))completionBlock { +- (void) start:(void (^)(NSError *error, NSArray * /* MCOIMAPFolder */ folders))completionBlock +{ _completionBlock = [completionBlock copy]; [self start]; } -- (void)operationCompleted { +- (void) cancel +{ + [_completionBlock release]; + _completionBlock = nil; + [super cancel]; +} + +- (void)operationCompleted +{ if (_completionBlock == NULL) return; nativeType *op = MCO_NATIVE_INSTANCE; if (op->error() == ErrorNone) { _completionBlock(nil, MCO_TO_OBJC(op->folders())); - } else { + } + else { _completionBlock([NSError mco_errorWithErrorCode:op->error()], nil); } [_completionBlock release]; diff --git a/src/objc/imap/MCOIMAPFetchMessagesOperation.mm b/src/objc/imap/MCOIMAPFetchMessagesOperation.mm index 5ae4cfe7..b310c022 100644 --- a/src/objc/imap/MCOIMAPFetchMessagesOperation.mm +++ b/src/objc/imap/MCOIMAPFetchMessagesOperation.mm @@ -38,12 +38,21 @@ typedef void (^CompletionType)(NSError *error, NSArray * messages, MCOIndexSet * [super dealloc]; } -- (void)start:(void (^)(NSError *error, NSArray * messages, MCOIndexSet * vanishedMessages))completionBlock { +- (void) start:(void (^)(NSError *error, NSArray * messages, MCOIndexSet * vanishedMessages))completionBlock +{ _completionBlock = [completionBlock copy]; [self start]; } -- (void)operationCompleted { +- (void) cancel +{ + [_completionBlock release]; + _completionBlock = nil; + [super cancel]; +} + +- (void) operationCompleted +{ if (_completionBlock == NULL) return; diff --git a/src/objc/imap/MCOIMAPFetchNamespaceOperation.mm b/src/objc/imap/MCOIMAPFetchNamespaceOperation.mm index 861298bf..33ff132c 100644 --- a/src/objc/imap/MCOIMAPFetchNamespaceOperation.mm +++ b/src/objc/imap/MCOIMAPFetchNamespaceOperation.mm @@ -38,12 +38,21 @@ typedef void (^CompletionType)(NSError *error, NSDictionary * namespaces); [super dealloc]; } -- (void)start:(void (^)(NSError *error, NSDictionary * namespaces))completionBlock { +- (void) start:(void (^)(NSError *error, NSDictionary * namespaces))completionBlock +{ _completionBlock = [completionBlock copy]; [self start]; } -- (void)operationCompleted { +- (void) cancel +{ + [_completionBlock release]; + _completionBlock = nil; + [super cancel]; +} + +- (void) operationCompleted +{ if (_completionBlock == NULL) return; diff --git a/src/objc/imap/MCOIMAPFolderInfoOperation.mm b/src/objc/imap/MCOIMAPFolderInfoOperation.mm index 61766073..dffff6fa 100644 --- a/src/objc/imap/MCOIMAPFolderInfoOperation.mm +++ b/src/objc/imap/MCOIMAPFolderInfoOperation.mm @@ -39,12 +39,21 @@ typedef void (^CompletionType)(NSError *error, MCOIMAPFolderInfo *info); [super dealloc]; } -- (void)start:(void (^)(NSError * error, MCOIMAPFolderInfo * info))completionBlock { +- (void)start:(void (^)(NSError * error, MCOIMAPFolderInfo * info))completionBlock +{ _completionBlock = [completionBlock copy]; [self start]; } -- (void)operationCompleted { +- (void) cancel +{ + [_completionBlock release]; + _completionBlock = nil; + [super cancel]; +} + +- (void) operationCompleted +{ if (_completionBlock == NULL) return; @@ -58,7 +67,8 @@ typedef void (^CompletionType)(NSError *error, MCOIMAPFolderInfo *info); [info setFirstUnseenUid:MCO_NATIVE_INSTANCE->firstUnseenUid()]; _completionBlock(nil, info); - } else { + } + else { _completionBlock([NSError mco_errorWithErrorCode:op->error()], nil); } [_completionBlock release]; diff --git a/src/objc/imap/MCOIMAPFolderStatusOperation.mm b/src/objc/imap/MCOIMAPFolderStatusOperation.mm index 2420e0b9..caf1ceb9 100644 --- a/src/objc/imap/MCOIMAPFolderStatusOperation.mm +++ b/src/objc/imap/MCOIMAPFolderStatusOperation.mm @@ -39,12 +39,21 @@ typedef void (^CompletionType)(NSError *error, MCOIMAPFolderStatus *status); [super dealloc]; } -- (void)start:(void (^)(NSError * error, MCOIMAPFolderStatus * status))completionBlock { +- (void) start:(void (^)(NSError * error, MCOIMAPFolderStatus * status))completionBlock +{ _completionBlock = [completionBlock copy]; [self start]; } -- (void)operationCompleted { +- (void) cancel +{ + [_completionBlock release]; + _completionBlock = nil; + [super cancel]; +} + +- (void) operationCompleted +{ if (_completionBlock == NULL) return; diff --git a/src/objc/imap/MCOIMAPIdentityOperation.mm b/src/objc/imap/MCOIMAPIdentityOperation.mm index f02fbba5..b5d65f9a 100644 --- a/src/objc/imap/MCOIMAPIdentityOperation.mm +++ b/src/objc/imap/MCOIMAPIdentityOperation.mm @@ -38,12 +38,21 @@ typedef void (^CompletionType)(NSError *error, NSDictionary * serverIdentity); [super dealloc]; } -- (void)start:(void (^)(NSError *error, NSDictionary * serverIdentity))completionBlock { +- (void) start:(void (^)(NSError *error, NSDictionary * serverIdentity))completionBlock +{ _completionBlock = [completionBlock copy]; [self start]; } -- (void)operationCompleted { +- (void) cancel +{ + [_completionBlock release]; + _completionBlock = nil; + [super cancel]; +} + +- (void) operationCompleted +{ if (_completionBlock == NULL) return; diff --git a/src/objc/imap/MCOIMAPIdleOperation.mm b/src/objc/imap/MCOIMAPIdleOperation.mm index d43bf818..eddf1fcf 100644 --- a/src/objc/imap/MCOIMAPIdleOperation.mm +++ b/src/objc/imap/MCOIMAPIdleOperation.mm @@ -38,12 +38,21 @@ typedef void (^CompletionType)(NSError *error); [super dealloc]; } -- (void)start:(void (^)(NSError *error))completionBlock { +- (void) start:(void (^)(NSError *error))completionBlock +{ _completionBlock = [completionBlock copy]; [self start]; } -- (void)operationCompleted { +- (void) cancel +{ + [_completionBlock release]; + _completionBlock = nil; + [super cancel]; +} + +- (void) operationCompleted +{ if (_completionBlock == NULL) return; diff --git a/src/objc/imap/MCOIMAPMessageRenderingOperation.mm b/src/objc/imap/MCOIMAPMessageRenderingOperation.mm index 983b6cac..4fb49bdb 100644 --- a/src/objc/imap/MCOIMAPMessageRenderingOperation.mm +++ b/src/objc/imap/MCOIMAPMessageRenderingOperation.mm @@ -39,12 +39,21 @@ typedef void (^CompletionType)(NSString * htmlString, NSError * error); [super dealloc]; } -- (void)start:(void (^)(NSString * htmlString, NSError * error))completionBlock { +- (void) start:(void (^)(NSString * htmlString, NSError * error))completionBlock +{ _completionBlock = [completionBlock copy]; [self start]; } -- (void)operationCompleted { +- (void) cancel +{ + [_completionBlock release]; + _completionBlock = nil; + [super cancel]; +} + +- (void) operationCompleted +{ if (_completionBlock == NULL) return; diff --git a/src/objc/imap/MCOIMAPOperation.mm b/src/objc/imap/MCOIMAPOperation.mm index 0b6d48e0..fafec6f2 100644 --- a/src/objc/imap/MCOIMAPOperation.mm +++ b/src/objc/imap/MCOIMAPOperation.mm @@ -27,12 +27,21 @@ typedef void (^CompletionType)(NSError *error); [super dealloc]; } -- (void)start:(void (^)(NSError *error))completionBlock { +- (void)start:(void (^)(NSError *error))completionBlock +{ _completionBlock = [completionBlock copy]; [self start]; } -- (void)operationCompleted { +- (void) cancel +{ + [_completionBlock release]; + _completionBlock = nil; + [super cancel]; +} + +- (void) operationCompleted +{ if (_completionBlock == NULL) return; diff --git a/src/objc/imap/MCOIMAPSearchOperation.mm b/src/objc/imap/MCOIMAPSearchOperation.mm index 730c73a0..4117a7a7 100644 --- a/src/objc/imap/MCOIMAPSearchOperation.mm +++ b/src/objc/imap/MCOIMAPSearchOperation.mm @@ -39,12 +39,21 @@ typedef void (^CompletionType)(NSError *error, MCOIndexSet * searchResult); [super dealloc]; } -- (void)start:(void (^)(NSError *error, MCOIndexSet * searchResult))completionBlock { +- (void) start:(void (^)(NSError *error, MCOIndexSet * searchResult))completionBlock +{ _completionBlock = [completionBlock copy]; [self start]; } -- (void)operationCompleted { +- (void) cancel +{ + [_completionBlock release]; + _completionBlock = nil; + [super cancel]; +} + +- (void) operationCompleted +{ if (_completionBlock == NULL) return; diff --git a/src/objc/pop/MCOPOPFetchHeaderOperation.mm b/src/objc/pop/MCOPOPFetchHeaderOperation.mm index ab467a76..c0201ef5 100644 --- a/src/objc/pop/MCOPOPFetchHeaderOperation.mm +++ b/src/objc/pop/MCOPOPFetchHeaderOperation.mm @@ -38,13 +38,21 @@ typedef void (^CompletionType)(NSError *error, MCOMessageHeader * header); [super dealloc]; } -- (void)start:(void (^)(NSError *error, MCOMessageHeader * header))completionBlock +- (void) start:(void (^)(NSError *error, MCOMessageHeader * header))completionBlock { _completionBlock = [completionBlock copy]; [self start]; } -- (void)operationCompleted { +- (void) cancel +{ + [_completionBlock release]; + _completionBlock = nil; + [super cancel]; +} + +- (void) operationCompleted +{ if (_completionBlock == NULL) return; diff --git a/src/objc/pop/MCOPOPFetchMessageOperation.mm b/src/objc/pop/MCOPOPFetchMessageOperation.mm index 02bad3ad..3f5f0000 100644 --- a/src/objc/pop/MCOPOPFetchMessageOperation.mm +++ b/src/objc/pop/MCOPOPFetchMessageOperation.mm @@ -75,12 +75,21 @@ private: [super dealloc]; } -- (void)start:(void (^)(NSError *error, NSData * messageData))completionBlock { +- (void) start:(void (^)(NSError *error, NSData * messageData))completionBlock +{ _completionBlock = [completionBlock copy]; [self start]; } -- (void)operationCompleted { +- (void) cancel +{ + [_completionBlock release]; + _completionBlock = nil; + [super cancel]; +} + +- (void) operationCompleted +{ if (_completionBlock == NULL) return; diff --git a/src/objc/pop/MCOPOPFetchMessagesOperation.mm b/src/objc/pop/MCOPOPFetchMessagesOperation.mm index 2fe9b31f..889baf74 100644 --- a/src/objc/pop/MCOPOPFetchMessagesOperation.mm +++ b/src/objc/pop/MCOPOPFetchMessagesOperation.mm @@ -38,13 +38,21 @@ typedef void (^CompletionType)(NSError *error, NSArray * messages); [super dealloc]; } -- (void)start:(void (^)(NSError *error, NSArray * messages))completionBlock +- (void) start:(void (^)(NSError *error, NSArray * messages))completionBlock { _completionBlock = [completionBlock copy]; [self start]; } -- (void)operationCompleted { +- (void) cancel +{ + [_completionBlock release]; + _completionBlock = nil; + [super cancel]; +} + +- (void) operationCompleted +{ if (_completionBlock == NULL) return; diff --git a/src/objc/smtp/MCOSMTPSendOperation.mm b/src/objc/smtp/MCOSMTPSendOperation.mm index 8a7d5b04..8394e2cc 100644 --- a/src/objc/smtp/MCOSMTPSendOperation.mm +++ b/src/objc/smtp/MCOSMTPSendOperation.mm @@ -57,7 +57,7 @@ private: return [[[self alloc] initWithMCOperation:op] autorelease]; } -- (id)initWithMCOperation:(mailcore::Operation *)op +- (id) initWithMCOperation:(mailcore::Operation *)op { self = [super initWithMCOperation:op]; @@ -75,14 +75,23 @@ private: [super dealloc]; } -- (void)start:(void (^)(NSError *error))completionBlock { +- (void) start:(void (^)(NSError *error))completionBlock +{ _completionBlock = [completionBlock copy]; [self start]; } +- (void) cancel +{ + [_completionBlock release]; + _completionBlock = nil; + [super cancel]; +} + // This method needs to be duplicated from MCOSMTPOperation since _completionBlock // references the instance of this subclass and not the one from MCOSMTPOperation. -- (void)operationCompleted { +- (void)operationCompleted +{ if (_completionBlock == NULL) return; diff --git a/src/ui/mac/MCOCIDURLProtocol.h b/src/ui/common/MCOCIDURLProtocol.h index ac4b0f2b..ac4b0f2b 100644 --- a/src/ui/mac/MCOCIDURLProtocol.h +++ b/src/ui/common/MCOCIDURLProtocol.h diff --git a/src/ui/mac/MCOCIDURLProtocol.mm b/src/ui/common/MCOCIDURLProtocol.mm index 83730c9d..ad529f54 100644 --- a/src/ui/mac/MCOCIDURLProtocol.mm +++ b/src/ui/common/MCOCIDURLProtocol.mm @@ -8,8 +8,6 @@ #import "MCOCIDURLProtocol.h" -#import "MCOMessageView.h" - #define MCOCIDURLProtocolDownloadedNotification @"MCOCIDURLProtocolDownloadedNotification" @implementation MCOCIDURLProtocol @@ -92,7 +90,6 @@ { NSDictionary * userInfo = [notification userInfo]; - //NSLog(@"downloaded?"); NSString * notifPartID = [userInfo objectForKey:@"PartUniqueID"]; MCOAbstractMessage * notifMessage = [userInfo objectForKey:@"Message"]; if (notifMessage != [self _message]) { @@ -102,8 +99,6 @@ return; } - //NSLog(@"downloaded2 %p %@", self, notifPartID); - NSData * data = [userInfo objectForKey:@"Data"]; NSURLResponse * response = [[NSURLResponse alloc] initWithURL:[[self request] URL] MIMEType:@"application/data" expectedContentLength:[data length] textEncodingName:nil]; @@ -142,7 +137,6 @@ } [[NSNotificationCenter defaultCenter] postNotificationName:MCOCIDURLProtocolDownloadedNotification object:nil userInfo:userInfo]; [userInfo release]; - //NSLog(@"downloaded %p %@", self, partUniqueID); } @end diff --git a/src/ui/ios/MCOMessageView.h b/src/ui/ios/MCOMessageView.h new file mode 100755 index 00000000..3c4ce50d --- /dev/null +++ b/src/ui/ios/MCOMessageView.h @@ -0,0 +1,50 @@ +// +// MCOMessageView.h +// testUI +// +// Created by DINH Viêt Hoà on 1/19/13. +// Copyright (c) 2013 MailCore. All rights reserved. +// + +#include <MailCore/MailCore.h> + +#import <UIKit/UIKit.h> + +@protocol MCOMessageViewDelegate; + +@interface MCOMessageView : UIView <UIWebViewDelegate> + +@property (nonatomic, copy) NSString * folder; +@property (nonatomic, strong) MCOAbstractMessage * message; + +@property (nonatomic, assign) id <MCOMessageViewDelegate> delegate; + +@property (nonatomic, assign) BOOL prefetchIMAPImagesEnabled; +@property (nonatomic, assign) BOOL prefetchIMAPAttachmentsEnabled; + +@end + +@protocol MCOMessageViewDelegate <NSObject> + +@optional +- (NSData *) MCOMessageView:(MCOMessageView *)view dataForPartWithUniqueID:(NSString *)partUniqueID; +- (void) MCOMessageView:(MCOMessageView *)view fetchDataForPartWithUniqueID:(NSString *)partUniqueID + downloadedFinished:(void (^)(NSError * error))downloadFinished; + +- (NSString *) MCOMessageView_templateForMainHeader:(MCOMessageView *)view; +- (NSString *) MCOMessageView_templateForImage:(MCOMessageView *)view; +- (NSString *) MCOMessageView_templateForAttachment:(MCOMessageView *)view; +- (NSString *) MCOMessageView_templateForMessage:(MCOMessageView *)view; +- (NSString *) MCOMessageView_templateForEmbeddedMessage:(MCOMessageView *)view; +- (NSString *) MCOMessageView_templateForEmbeddedMessageHeader:(MCOMessageView *)view; +- (NSString *) MCOMessageView_templateForAttachmentSeparator:(MCOMessageView *)view; + +- (NSDictionary *) MCOMessageView:(MCOMessageView *)view templateValuesForPartWithUniqueID:(NSString *)uniqueID; +- (NSDictionary *) MCOMessageView:(MCOMessageView *)view templateValuesForHeader:(MCOMessageHeader *)header; +- (BOOL) MCOMessageView:(MCOMessageView *)view canPreviewPart:(MCOAbstractPart *)part; + +- (NSString *) MCOMessageView:(MCOMessageView *)view filteredHTMLForPart:(NSString *)html; +- (NSString *) MCOMessageView:(MCOMessageView *)view filteredHTMLForMessage:(NSString *)html; +- (NSData *) MCOMessageView:(MCOMessageView *)view previewForData:(NSData *)data isHTMLInlineImage:(BOOL)isHTMLInlineImage; + +@end diff --git a/src/ui/ios/MCOMessageView.mm b/src/ui/ios/MCOMessageView.mm new file mode 100755 index 00000000..e3786bb5 --- /dev/null +++ b/src/ui/ios/MCOMessageView.mm @@ -0,0 +1,416 @@ +// +// MCOMessageView.m +// testUI +// +// Created by DINH Viêt Hoà on 1/19/13. +// Copyright (c) 2013 MailCore. All rights reserved. +// + +#import "MCOMessageView.h" +#import "MCOCIDURLProtocol.h" + +static NSString * mainJavascript = @"\ +var imageElements = function() {\ + var imageNodes = document.getElementsByTagName('img');\ + return [].slice.call(imageNodes);\ +};\ +\ +var findCIDImageURL = function() {\ + var images = imageElements();\ + \ + var imgLinks = [];\ + for (var i = 0; i < images.length; i++) {\ + var url = images[i].getAttribute('src');\ + if (url.indexOf('cid:') == 0 || url.indexOf('x-mailcore-image:') == 0)\ + imgLinks.push(url);\ + }\ + return JSON.stringify(imgLinks);\ +};\ +\ +var replaceImageSrc = function(info) {\ + var images = imageElements();\ + \ + for (var i = 0; i < images.length; i++) {\ + var url = images[i].getAttribute('src');\ + if (url.indexOf(info.URLKey) == 0) {\ + images[i].setAttribute('src', info.LocalPathKey);\ + break;\ + }\ + }\ +};\ +"; + +static NSString * mainStyle = @"\ +body {\ + font-family: Helvetica;\ + font-size: 14px;\ + word-wrap: break-word;\ + -webkit-text-size-adjust:none;\ + -webkit-nbsp-mode: space;\ +}\ +\ +pre {\ + white-space: pre-wrap;\ +}\ +"; + +@interface MCOMessageView () <MCOHTMLRendererIMAPDelegate> + +@end + +@implementation MCOMessageView { + UIWebView * _webView; + NSString * _folder; + MCOAbstractMessage * _message; + id <MCOMessageViewDelegate> _delegate; + BOOL _prefetchIMAPImagesEnabled; + BOOL _prefetchIMAPAttachmentsEnabled; +} + +@synthesize folder = _folder; +@synthesize delegate = _delegate; +@synthesize prefetchIMAPImagesEnabled = _prefetchIMAPImagesEnabled; +@synthesize prefetchIMAPAttachmentsEnabled = _prefetchIMAPAttachmentsEnabled; + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + + _webView = [[UIWebView alloc] initWithFrame:[self bounds]]; + [_webView setAutoresizingMask:(UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth)]; + [_webView setDelegate:self]; + [self addSubview:_webView]; + + return self; +} + +- (void) dealloc +{ + [_message release]; + [_folder release]; + [_webView release]; + + [super dealloc]; +} + +- (void) setMessage:(MCOAbstractMessage *)message +{ + [_message release]; + _message = [message retain]; + + [_webView stopLoading]; + [self _refresh]; +} + +- (MCOAbstractMessage *) message +{ + return _message; +} + +- (void) _refresh +{ + NSString * content; + + if (_message == nil) { + content = nil; + } + else { + if ([_message isKindOfClass:[MCOIMAPMessage class]]) { + content = [(MCOIMAPMessage *) _message htmlRenderingWithFolder:_folder delegate:self]; + } + else if ([_message isKindOfClass:[MCOMessageBuilder class]]) { + content = [(MCOMessageBuilder *) _message htmlRenderingWithDelegate:self]; + } + else if ([_message isKindOfClass:[MCOMessageParser class]]) { + content = [(MCOMessageParser *) _message htmlRenderingWithDelegate:self]; + } + else { + content = nil; + MCAssert(0); + } + } + if (content == nil) { + [_webView loadHTMLString:@"" baseURL:nil]; + return; + } + + NSMutableString * html = [NSMutableString string]; + [html appendFormat:@"<html><head><script>%@</script><style>%@</style></head>" + @"<body>%@</body><iframe src='x-mailcore-msgviewloaded:' style='width: 0px; height: 0px; border: none;'>" + @"</iframe></html>", mainJavascript, mainStyle, content]; + [_webView loadHTMLString:html baseURL:nil]; +} + +- (void) _loadImages +{ + NSString * result = [_webView stringByEvaluatingJavaScriptFromString:@"findCIDImageURL()"]; + NSLog(@"----------"); + NSLog(@"%@", result); + NSData * data = [result dataUsingEncoding:NSUTF8StringEncoding]; + NSError *error = nil; + NSArray * imagesURLStrings = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; + + for(NSString * urlString in imagesURLStrings) { + MCOAbstractPart * part = nil; + NSURL * url; + + url = [NSURL URLWithString:urlString]; + if ([MCOCIDURLProtocol isCID:url]) { + part = [self _partForCIDURL:url]; + } + else if ([MCOCIDURLProtocol isXMailcoreImage:url]) { + NSString * specifier = [url resourceSpecifier]; + NSString * partUniqueID = specifier; + part = [self _partForUniqueID:partUniqueID]; + } + + if (part == nil) + continue; + + NSString * partUniqueID = [part uniqueID]; + NSData * data = [[self delegate] MCOMessageView:self dataForPartWithUniqueID:partUniqueID]; + + void (^replaceImages)(NSError *error) = ^(NSError *error) { + NSData * downloadedData = [[self delegate] MCOMessageView:self dataForPartWithUniqueID:partUniqueID]; + NSData * previewData = [[self delegate] MCOMessageView:self previewForData:downloadedData isHTMLInlineImage:[MCOCIDURLProtocol isCID:url]]; + NSString * filename = [NSString stringWithFormat:@"%lu", (unsigned long)urlString.hash]; + NSURL * cacheURL = [self _cacheJPEGImageData:previewData withFilename:filename]; + + NSDictionary * args = @{ @"URLKey": urlString, @"LocalPathKey": cacheURL.absoluteString }; + NSString * jsonString = [self _jsonEscapedStringFromDictionary:args]; + + NSString * replaceScript = [NSString stringWithFormat:@"replaceImageSrc(%@)", jsonString]; + [_webView stringByEvaluatingJavaScriptFromString:replaceScript]; + }; + + if (data == nil) { + [[self delegate] MCOMessageView:self fetchDataForPartWithUniqueID:partUniqueID downloadedFinished:^(NSError * error) { + replaceImages(error); + }]; + } else { + replaceImages(nil); + } + } +} + +- (NSString *) _jsonEscapedStringFromDictionary:(NSDictionary *)dictionary +{ + NSData * json = [NSJSONSerialization dataWithJSONObject:dictionary options:0 error:nil]; + NSString * jsonString = [[NSString alloc] initWithData:json encoding:NSUTF8StringEncoding]; + return jsonString; +} + +- (NSURL *) _cacheJPEGImageData:(NSData *)imageData withFilename:(NSString *)filename +{ + NSString * path = [[NSTemporaryDirectory() stringByAppendingPathComponent:filename] stringByAppendingPathExtension:@"jpg"]; + [imageData writeToFile:path atomically:YES]; + return [NSURL fileURLWithPath:path]; +} + +- (MCOAbstractPart *) _partForCIDURL:(NSURL *)url +{ + return [_message partForContentID:[url resourceSpecifier]]; +} + +- (MCOAbstractPart *) _partForUniqueID:(NSString *)partUniqueID +{ + return [_message partForUniqueID:partUniqueID]; +} + +- (NSData *) _dataForIMAPPart:(MCOIMAPPart *)part folder:(NSString *)folder +{ + NSData * data; + NSString * partUniqueID = [part uniqueID]; + data = [[self delegate] MCOMessageView:self dataForPartWithUniqueID:partUniqueID]; + if (data == NULL) { + [[self delegate] MCOMessageView:self fetchDataForPartWithUniqueID:partUniqueID downloadedFinished:^(NSError * error) { + [self _refresh]; + }]; + } + return data; +} + +- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { + + NSURLRequest *responseRequest = [self webView:webView resource:nil willSendRequest:request redirectResponse:nil fromDataSource:nil]; + + if(responseRequest == request) { + return YES; + } else { + [webView loadRequest:responseRequest]; + return NO; + } +} + +- (NSURLRequest *)webView:(UIWebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(id)dataSource +{ + if ([[[request URL] scheme] isEqualToString:@"x-mailcore-msgviewloaded"]) { + [self _loadImages]; + } + + return request; +} + +- (BOOL) MCOAbstractMessage:(MCOAbstractMessage *)msg canPreviewPart:(MCOAbstractPart *)part +{ + static NSMutableSet * supportedImageMimeTypes = NULL; + if (supportedImageMimeTypes == NULL) { + supportedImageMimeTypes = [[NSMutableSet alloc] init]; + [supportedImageMimeTypes addObject:@"image/png"]; + [supportedImageMimeTypes addObject:@"image/gif"]; + [supportedImageMimeTypes addObject:@"image/jpg"]; + [supportedImageMimeTypes addObject:@"image/jpeg"]; + } + static NSMutableSet * supportedImageExtension = NULL; + if (supportedImageExtension == NULL) { + supportedImageExtension = [[NSMutableSet alloc] init]; + [supportedImageExtension addObject:@"png"]; + [supportedImageExtension addObject:@"gif"]; + [supportedImageExtension addObject:@"jpg"]; + [supportedImageExtension addObject:@"jpeg"]; + } + + if ([supportedImageMimeTypes containsObject:[[part mimeType] lowercaseString]]) { + return YES; + } + + NSString * ext = nil; + if ([part filename] != nil) { + if ([[part filename] pathExtension] != nil) { + ext = [[[part filename] pathExtension] lowercaseString]; + } + } + if (ext != nil) { + if ([supportedImageExtension containsObject:ext]) + return YES; + } + + if (![[self delegate] respondsToSelector:@selector(MCOMessageView:canPreviewPart:)]) { + return NO; + } + return [[self delegate] MCOMessageView:self canPreviewPart:part]; +} + +- (NSDictionary *) MCOAbstractMessage:(MCOAbstractMessage *)msg templateValuesForHeader:(MCOMessageHeader *)header +{ + if (![[self delegate] respondsToSelector:@selector(MCOMessageView:templateValuesForHeader:)]) { + return nil; + } + return [[self delegate] MCOMessageView:self templateValuesForHeader:header]; +} + +- (NSDictionary *) MCOAbstractMessage:(MCOAbstractMessage *)msg templateValuesForPart:(MCOAbstractPart *)part +{ + if (![[self delegate] respondsToSelector:@selector(MCOMessageView:templateValuesForPartWithUniqueID:)]) { + return nil; + } + return [[self delegate] MCOMessageView:self templateValuesForPartWithUniqueID:[part uniqueID]]; +} + +- (NSString *) MCOAbstractMessage:(MCOAbstractMessage *)msg templateForMainHeader:(MCOMessageHeader *)header +{ + if (![[self delegate] respondsToSelector:@selector(MCOMessageView_templateForMainHeader:)]) { + return nil; + } + return [[self delegate] MCOMessageView_templateForMainHeader:self]; +} + +- (NSString *) MCOAbstractMessage:(MCOAbstractMessage *)msg templateForImage:(MCOAbstractPart *)header +{ + NSString * templateString; + if ([[self delegate] respondsToSelector:@selector(MCOMessageView_templateForImage:)]) { + templateString = [[self delegate] MCOMessageView_templateForImage:self]; + } + else { + templateString = @"<img src=\"{{URL}}\"/>"; + } + templateString = [NSString stringWithFormat:@"<div id=\"{{CONTENTID}}\">%@</div>", templateString]; + return templateString; +} + +- (NSString *) MCOAbstractMessage:(MCOAbstractMessage *)msg templateForAttachment:(MCOAbstractPart *)part +{ + if (![[self delegate] respondsToSelector:@selector(MCOMessageView_templateForAttachment:)]) { + return NULL; + } + NSString * templateString = [[self delegate] MCOMessageView_templateForAttachment:self]; + templateString = [NSString stringWithFormat:@"<div id=\"{{CONTENTID}}\">%@</div>", templateString]; + return templateString; +} + +- (NSString *) MCOAbstractMessage_templateForMessage:(MCOAbstractMessage *)msg +{ + if (![[self delegate] respondsToSelector:@selector(MCOMessageView_templateForMessage:)]) { + return NULL; + } + return [[self delegate] MCOMessageView_templateForMessage:self]; +} + +- (NSString *) MCOAbstractMessage:(MCOAbstractMessage *)msg templateForEmbeddedMessage:(MCOAbstractMessagePart *)part +{ + if (![[self delegate] respondsToSelector:@selector(MCOMessageView_templateForEmbeddedMessage:)]) { + return NULL; + } + return [[self delegate] MCOMessageView_templateForEmbeddedMessage:self]; +} + +- (NSString *) MCOAbstractMessage:(MCOAbstractMessage *)msg templateForEmbeddedMessageHeader:(MCOMessageHeader *)header +{ + if (![[self delegate] respondsToSelector:@selector(MCOMessageView_templateForEmbeddedMessageHeader:)]) { + return NULL; + } + return [[self delegate] MCOMessageView_templateForEmbeddedMessageHeader:self]; +} + +- (NSString *) MCOAbstractMessage_templateForAttachmentSeparator:(MCOAbstractMessage *)msg +{ + if (![[self delegate] respondsToSelector:@selector(MCOMessageView_templateForAttachmentSeparator:)]) { + return NULL; + } + return [[self delegate] MCOMessageView_templateForAttachmentSeparator:self]; +} + +- (NSString *) MCOAbstractMessage:(MCOAbstractMessage *)msg filterHTMLForPart:(NSString *)html +{ + if (![[self delegate] respondsToSelector:@selector(MCOMessageView:filteredHTMLForPart:)]) { + return html; + } + return [[self delegate] MCOMessageView:self filteredHTMLForPart:html]; +} + +- (NSString *) MCOAbstractMessage:(MCOAbstractMessage *)msg filterHTMLForMessage:(NSString *)html +{ + if (![[self delegate] respondsToSelector:@selector(MCOMessageView:filteredHTMLForMessage:)]) { + return html; + } + return [[self delegate] MCOMessageView:self filteredHTMLForMessage:html]; +} + +- (NSData *) MCOAbstractMessage:(MCOAbstractMessage *)msg dataForIMAPPart:(MCOIMAPPart *)part folder:(NSString *)folder +{ + return [self _dataForIMAPPart:part folder:folder]; +} + +- (void) MCOAbstractMessage:(MCOAbstractMessage *)msg prefetchAttachmentIMAPPart:(MCOIMAPPart *)part folder:(NSString *)folder +{ + if (!_prefetchIMAPAttachmentsEnabled) + return; + + NSString * partUniqueID = [part uniqueID]; + [[self delegate] MCOMessageView:self fetchDataForPartWithUniqueID:partUniqueID downloadedFinished:^(NSError * error) { + // do nothing + }]; +} + +- (void) MCOAbstractMessage:(MCOAbstractMessage *)msg prefetchImageIMAPPart:(MCOIMAPPart *)part folder:(NSString *)folder +{ + if (!_prefetchIMAPImagesEnabled) + return; + + NSString * partUniqueID = [part uniqueID]; + [[self delegate] MCOMessageView:self fetchDataForPartWithUniqueID:partUniqueID downloadedFinished:^(NSError * error) { + // do nothing + }]; +} + +@end |