From 1d78534d1d708100e345a7964001104f91daad10 Mon Sep 17 00:00:00 2001 From: Mathias Leppich Date: Mon, 26 Aug 2013 20:38:11 +0200 Subject: [PATCH 1/3] use gitx://custom.css to load user style-sheet from ~/.gitxcustom.css --- Classes/git/PBGitXProtocol.m | 42 ++++++++++++++++++++++++++++++----- html/views/commit/index.html | 1 + html/views/diff/index.html | 1 + html/views/history/index.html | 1 + 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/Classes/git/PBGitXProtocol.m b/Classes/git/PBGitXProtocol.m index 93a19c953..d1c5005cb 100644 --- a/Classes/git/PBGitXProtocol.m +++ b/Classes/git/PBGitXProtocol.m @@ -24,15 +24,45 @@ + (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request -(void)startLoading { NSURL *url = [[self request] URL]; + + if ([[url host] isEqualToString:@"custom.css"]) { + [self startLoadingCustomCSS]; + return; + } + PBGitRepository *repo = [[self request] repository]; - - if(!repo) { - [[self client] URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:0 userInfo:nil]]; - return; + NSString * commit = [url host]; + NSString * filepath = [url path]; + if (repo) { + [self startLoadingGitFile:filepath atCommit:commit withRepository:repo]; + return; } + + [[self client] URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:0 userInfo:nil]]; +} + +- (void)startLoadingCustomCSS +{ + NSString * filepath = @"~/.gitxcustom.css"; + NSFileHandle * filehandle = [NSFileHandle fileHandleForReadingAtPath:[filepath stringByExpandingTildeInPath]]; + [self startLoadingToEndOfFileHandle:filehandle]; +} - NSString *specifier = [NSString stringWithFormat:@"%@:%@", [url host], [[url path] substringFromIndex:1]]; - handle = [repo handleInWorkDirForArguments:[NSArray arrayWithObjects:@"cat-file", @"blob", specifier, nil]]; +- (void)startLoadingGitFile:(NSString *)filepath atCommit:(NSString *)commit withRepository:(PBGitRepository *)repo +{ + NSString *specifier = [NSString stringWithFormat:@"%@:%@", commit, [filepath substringFromIndex:1]]; + NSFileHandle * filehandle = [repo handleInWorkDirForArguments:[NSArray arrayWithObjects:@"cat-file", @"blob", specifier, nil]]; + [self startLoadingToEndOfFileHandle:filehandle]; +} + +- (void)startLoadingToEndOfFileHandle:(NSFileHandle *)handle_ +{ + if (handle_ == nil) { + [[self client] URLProtocol:self didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:0 userInfo:nil]]; + return; + } + + handle = handle_; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didFinishFileLoad:) name:NSFileHandleReadToEndOfFileCompletionNotification object:handle]; [handle readToEndOfFileInBackgroundAndNotify]; diff --git a/html/views/commit/index.html b/html/views/commit/index.html index b69ef18b1..5778fffd6 100644 --- a/html/views/commit/index.html +++ b/html/views/commit/index.html @@ -9,6 +9,7 @@ + diff --git a/html/views/diff/index.html b/html/views/diff/index.html index 00abee546..6a17a8111 100644 --- a/html/views/diff/index.html +++ b/html/views/diff/index.html @@ -9,6 +9,7 @@ + + From e57a4db3c7831c1ac89344799a8b6602903247a4 Mon Sep 17 00:00:00 2001 From: Mathias Leppich Date: Thu, 31 Oct 2013 12:35:28 +0100 Subject: [PATCH 2/3] add Matt Gallagher's NSFileManager extension to locate and create Application Support directory see: http://www.cocoawithlove.com/2010/05/finding-or-creating-application-support.html --- .../Util/NSFileManager+DirectoryLocations.h | 36 ++++ .../Util/NSFileManager+DirectoryLocations.m | 155 ++++++++++++++++++ GitX.xcodeproj/project.pbxproj | 8 + 3 files changed, 199 insertions(+) create mode 100644 Classes/Util/NSFileManager+DirectoryLocations.h create mode 100644 Classes/Util/NSFileManager+DirectoryLocations.m diff --git a/Classes/Util/NSFileManager+DirectoryLocations.h b/Classes/Util/NSFileManager+DirectoryLocations.h new file mode 100644 index 000000000..2ffd42ad3 --- /dev/null +++ b/Classes/Util/NSFileManager+DirectoryLocations.h @@ -0,0 +1,36 @@ +// +// NSFileManager+DirectoryLocations.h +// +// Created by Matt Gallagher on 06 May 2010 +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. Permission is granted to anyone to +// use this software for any purpose, including commercial applications, and to +// alter it and redistribute it freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#import + +// +// DirectoryLocations is a set of global methods for finding the fixed location +// directoriess. +// +@interface NSFileManager (DirectoryLocations) + +- (NSString *)findOrCreateDirectory:(NSSearchPathDirectory)searchPathDirectory + inDomain:(NSSearchPathDomainMask)domainMask + appendPathComponent:(NSString *)appendComponent + error:(NSError **)errorOut; +- (NSString *)applicationSupportDirectory; + +@end diff --git a/Classes/Util/NSFileManager+DirectoryLocations.m b/Classes/Util/NSFileManager+DirectoryLocations.m new file mode 100644 index 000000000..4de2c3618 --- /dev/null +++ b/Classes/Util/NSFileManager+DirectoryLocations.m @@ -0,0 +1,155 @@ +// +// NSFileManager+DirectoryLocations.m +// +// Created by Matt Gallagher on 06 May 2010 +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. Permission is granted to anyone to +// use this software for any purpose, including commercial applications, and to +// alter it and redistribute it freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// 3. This notice may not be removed or altered from any source +// distribution. +// + +#import "NSFileManager+DirectoryLocations.h" + +enum +{ + DirectoryLocationErrorNoPathFound, + DirectoryLocationErrorFileExistsAtLocation +}; + +NSString * const DirectoryLocationDomain = @"DirectoryLocationDomain"; + +@implementation NSFileManager (DirectoryLocations) + +// +// findOrCreateDirectory:inDomain:appendPathComponent:error: +// +// Method to tie together the steps of: +// 1) Locate a standard directory by search path and domain mask +// 2) Select the first path in the results +// 3) Append a subdirectory to that path +// 4) Create the directory and intermediate directories if needed +// 5) Handle errors by emitting a proper NSError object +// +// Parameters: +// searchPathDirectory - the search path passed to NSSearchPathForDirectoriesInDomains +// domainMask - the domain mask passed to NSSearchPathForDirectoriesInDomains +// appendComponent - the subdirectory appended +// errorOut - any error from file operations +// +// returns the path to the directory (if path found and exists), nil otherwise +// +- (NSString *)findOrCreateDirectory:(NSSearchPathDirectory)searchPathDirectory + inDomain:(NSSearchPathDomainMask)domainMask + appendPathComponent:(NSString *)appendComponent + error:(NSError **)errorOut +{ + // + // Search for the path + // + NSArray* paths = NSSearchPathForDirectoriesInDomains( + searchPathDirectory, + domainMask, + YES); + if ([paths count] == 0) + { + if (errorOut) + { + NSDictionary *userInfo = + [NSDictionary dictionaryWithObjectsAndKeys: + NSLocalizedStringFromTable( + @"No path found for directory in domain.", + @"Errors", + nil), + NSLocalizedDescriptionKey, + [NSNumber numberWithInteger:searchPathDirectory], + @"NSSearchPathDirectory", + [NSNumber numberWithInteger:domainMask], + @"NSSearchPathDomainMask", + nil]; + *errorOut = + [NSError + errorWithDomain:DirectoryLocationDomain + code:DirectoryLocationErrorNoPathFound + userInfo:userInfo]; + } + return nil; + } + + // + // Normally only need the first path returned + // + NSString *resolvedPath = [paths objectAtIndex:0]; + + // + // Append the extra path component + // + if (appendComponent) + { + resolvedPath = [resolvedPath + stringByAppendingPathComponent:appendComponent]; + } + + // + // Create the path if it doesn't exist + // + NSError *error = nil; + BOOL success = [self + createDirectoryAtPath:resolvedPath + withIntermediateDirectories:YES + attributes:nil + error:&error]; + if (!success) + { + if (errorOut) + { + *errorOut = error; + } + return nil; + } + + // + // If we've made it this far, we have a success + // + if (errorOut) + { + *errorOut = nil; + } + return resolvedPath; +} + +// +// applicationSupportDirectory +// +// Returns the path to the applicationSupportDirectory (creating it if it doesn't +// exist). +// +- (NSString *)applicationSupportDirectory +{ + NSString *executableName = + [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleExecutable"]; + NSError *error; + NSString *result = + [self + findOrCreateDirectory:NSApplicationSupportDirectory + inDomain:NSUserDomainMask + appendPathComponent:executableName + error:&error]; + if (!result) + { + NSLog(@"Unable to find or create application support directory:\n%@", error); + } + return result; +} + +@end diff --git a/GitX.xcodeproj/project.pbxproj b/GitX.xcodeproj/project.pbxproj index c6fcd3205..1912558a3 100644 --- a/GitX.xcodeproj/project.pbxproj +++ b/GitX.xcodeproj/project.pbxproj @@ -181,6 +181,8 @@ 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; 911112370E5A097800BF76B4 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 911112360E5A097800BF76B4 /* Security.framework */; }; 913D5E500E55645900CECEA2 /* gitx in Resources */ = {isa = PBXBuildFile; fileRef = 913D5E490E55644600CECEA2 /* gitx */; }; + A27BDC65182267E600251A23 /* NSFileManager+DirectoryLocations.m in Sources */ = {isa = PBXBuildFile; fileRef = A27BDC64182267E600251A23 /* NSFileManager+DirectoryLocations.m */; }; + A27BDC66182267E600251A23 /* NSFileManager+DirectoryLocations.m in Sources */ = {isa = PBXBuildFile; fileRef = A27BDC64182267E600251A23 /* NSFileManager+DirectoryLocations.m */; }; BC0444AD17648CC900353E6D /* AddRemoteTemplate.png in Resources */ = {isa = PBXBuildFile; fileRef = BC0444AC17648CC900353E6D /* AddRemoteTemplate.png */; }; BC0444B817648D0200353E6D /* BranchHighlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = BC0444B717648D0200353E6D /* BranchHighlighted.png */; }; BC0444BA17648DA800353E6D /* FolderHighlighted.png in Resources */ = {isa = PBXBuildFile; fileRef = BC0444B917648DA700353E6D /* FolderHighlighted.png */; }; @@ -644,6 +646,8 @@ 8D1107320486CEB800E47090 /* GitX.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GitX.app; sourceTree = BUILT_PRODUCTS_DIR; }; 911112360E5A097800BF76B4 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = ""; }; 913D5E490E55644600CECEA2 /* gitx */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = gitx; sourceTree = BUILT_PRODUCTS_DIR; }; + A27BDC63182267E600251A23 /* NSFileManager+DirectoryLocations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSFileManager+DirectoryLocations.h"; sourceTree = ""; }; + A27BDC64182267E600251A23 /* NSFileManager+DirectoryLocations.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSFileManager+DirectoryLocations.m"; sourceTree = ""; }; BC0444AC17648CC900353E6D /* AddRemoteTemplate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = AddRemoteTemplate.png; sourceTree = ""; }; BC0444B717648D0200353E6D /* BranchHighlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = BranchHighlighted.png; sourceTree = ""; }; BC0444B917648DA700353E6D /* FolderHighlighted.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = FolderHighlighted.png; sourceTree = ""; }; @@ -1104,6 +1108,8 @@ 4A5D76A414A9A9CC00DF6C68 /* Util */ = { isa = PBXGroup; children = ( + A27BDC63182267E600251A23 /* NSFileManager+DirectoryLocations.h */, + A27BDC64182267E600251A23 /* NSFileManager+DirectoryLocations.m */, 4A5D76A514A9A9CC00DF6C68 /* NSApplication+GitXScripting.h */, 4A5D76A614A9A9CC00DF6C68 /* NSApplication+GitXScripting.m */, 4A5D76A714A9A9CC00DF6C68 /* NSFileHandleExt.h */, @@ -1564,6 +1570,7 @@ 4A5D76E914A9A9CC00DF6C68 /* PBGitWindowController.m in Sources */, 4A5D76EA14A9A9CC00DF6C68 /* PBHistorySearchController.m in Sources */, 4A5D76EB14A9A9CC00DF6C68 /* PBPrefsWindowController.m in Sources */, + A27BDC65182267E600251A23 /* NSFileManager+DirectoryLocations.m in Sources */, 4A5D76EC14A9A9CC00DF6C68 /* PBRefController.m in Sources */, 4A5D76ED14A9A9CC00DF6C68 /* PBRepositoryDocumentController.m in Sources */, 4A5D76EE14A9A9CC00DF6C68 /* PBServicesController.m in Sources */, @@ -1650,6 +1657,7 @@ buildActionMask = 2147483647; files = ( 4A5D773A14A9A9F600DF6C68 /* gitx.m in Sources */, + A27BDC66182267E600251A23 /* NSFileManager+DirectoryLocations.m in Sources */, 4A5D773C14A9AA2F00DF6C68 /* PBGitBinary.m in Sources */, 4A5D773D14A9AA3700DF6C68 /* PBEasyPipe.m in Sources */, 4AB057E41652652000DE751D /* GitRepoFinder.m in Sources */, From fce5f9f311b584772fc96f0318c33507142f990f Mon Sep 17 00:00:00 2001 From: Mathias Leppich Date: Thu, 31 Oct 2013 12:37:39 +0100 Subject: [PATCH 3/3] load custom.css file from application support folder: `~/Library/Application Support/GitX/Custom.css` --- Classes/git/PBGitXProtocol.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Classes/git/PBGitXProtocol.m b/Classes/git/PBGitXProtocol.m index d1c5005cb..1a5db697f 100644 --- a/Classes/git/PBGitXProtocol.m +++ b/Classes/git/PBGitXProtocol.m @@ -8,6 +8,7 @@ #import "PBGitXProtocol.h" +#import "NSFileManager+DirectoryLocations.h" @implementation PBGitXProtocol @@ -43,7 +44,7 @@ -(void)startLoading - (void)startLoadingCustomCSS { - NSString * filepath = @"~/.gitxcustom.css"; + NSString * filepath = [[[NSFileManager defaultManager] applicationSupportDirectory] stringByAppendingPathComponent:@"Custom.css"]; NSFileHandle * filehandle = [NSFileHandle fileHandleForReadingAtPath:[filepath stringByExpandingTildeInPath]]; [self startLoadingToEndOfFileHandle:filehandle]; }