Compare commits

...
2 Commits
5 changed files with 209 additions and 14 deletions
+17 -4
View File
@@ -210,10 +210,10 @@ var CPDocumentUntitledCount = 0;
@throws CPUnsupportedMethodException if this method hasn't been overriden by the subclass @throws CPUnsupportedMethodException if this method hasn't been overriden by the subclass
@return the document data @return the document data
*/ */
- (CPData)dataOfType:(CPString)aType error:({CPError})anError - (CPData)dataOfType:(CPString)aType
{ {
[CPException raise:CPUnsupportedMethodException [CPException raise:CPUnsupportedMethodException
reason:"dataOfType:error: must be overridden by the document subclass."]; reason:"dataOfType: must be overridden by the document subclass."];
} }
/*! /*!
@@ -473,8 +473,21 @@ var CPDocumentUntitledCount = 0;
*/ */
- (void)saveToURL:(CPURL)anAbsoluteURL ofType:(CPString)aTypeName forSaveOperation:(CPSaveOperationType)aSaveOperation delegate:(id)aDelegate didSaveSelector:(SEL)aDidSaveSelector contextInfo:(id)aContextInfo - (void)saveToURL:(CPURL)anAbsoluteURL ofType:(CPString)aTypeName forSaveOperation:(CPSaveOperationType)aSaveOperation delegate:(id)aDelegate didSaveSelector:(SEL)aDidSaveSelector contextInfo:(id)aContextInfo
{ {
var data = [self dataOfType:[self fileType] error:nil], if (anAbsoluteURL.isLocalStorageURL())
oldChangeCount = _changeCount; [[CPDocumentController sharedDocumentController] _addLocalDocumentURL:anAbsoluteURL];
var data = nil;
if ([self respondsToSelector:@selector(dataOfType:error:)])
{
CPLog.warn("[" + CPStringFromClass([self class]) + " " + CPStringFromSelector(@selector(dataOfType:error:)) + "] is deprecated, please implement " + CPStringFromSelector(@selector(dataOfType:)) + " instead and simply throw exceptions when necessary.");
data = [self dataOfType:[self fileType] error:nil];
}
else
data = [self dataOfType:[self fileType]];
var oldChangeCount = _changeCount;
_writeRequest = [CPURLRequest requestWithURL:anAbsoluteURL]; _writeRequest = [CPURLRequest requestWithURL:anAbsoluteURL];
+59 -4
View File
@@ -38,6 +38,7 @@ var CPSharedDocumentController = nil;
{ {
CPArray _documents; CPArray _documents;
CPArray _documentTypes; CPArray _documentTypes;
CPArray _localDocumentURLs;
} }
/*! /*!
@@ -59,14 +60,30 @@ var CPSharedDocumentController = nil;
- (id)init - (id)init
{ {
self = [super init]; self = [super init];
if (self) if (self)
{ {
_documents = [[CPArray alloc] init];
if (!CPSharedDocumentController) if (!CPSharedDocumentController)
CPSharedDocumentController = self; CPSharedDocumentController = self;
_localDocumentURLs = [CPSet set];
if (window.localStorage)
{
var localDocumentURLs = localStorage.getItem(CPDocumentControllerLocalDocumentURLsKey);
if (localDocumentURLs)
{
localDocumentURLs = JSON.parse(localDocumentURLs);
var count = [localDocumentURLs count];
while (count--)
[_localDocumentURLs addObject:new CFURL(localDocumentURLs[count])];
}
}
_documents = [];
_documentTypes = [[[CPBundle mainBundle] infoDictionary] objectForKey:@"CPBundleDocumentTypes"]; _documentTypes = [[[CPBundle mainBundle] infoDictionary] objectForKey:@"CPBundleDocumentTypes"];
} }
return self; return self;
@@ -219,7 +236,7 @@ var CPSharedDocumentController = nil;
Opens a new document in the application. Opens a new document in the application.
@param aSender the requesting object @param aSender the requesting object
*/ */
- (CFAction)newDocument:(id)aSender - (@action)newDocument:(id)aSender
{ {
[self openUntitledDocumentOfType:[[_documentTypes objectAtIndex:0] objectForKey:@"CPBundleTypeName"] display:YES]; [self openUntitledDocumentOfType:[[_documentTypes objectAtIndex:0] objectForKey:@"CPBundleTypeName"] display:YES];
} }
@@ -455,3 +472,41 @@ var CPSharedDocumentController = nil;
} }
@end @end
var CPDocumentControllerLocalDocumentURLsKey = @"Cappuccino.CPDocumentController.documentURLs";
@implementation CPDocumentController (LocalStorage)
- (void)_addLocalDocumentURL:(CPURL)aURL
{
if (!window.localStorage)
return;
[_localDocumentURLs addObject:aURL];
var stringURLs = [],
URL = nil,
URLEnumerator = [_localDocumentURLs objectEnumerator];
while (URL = [URLEnumerator nextObject])
stringURLs.push(URL + "");
localStorage.setItem(CPDocumentControllerLocalDocumentURLsKey, JSON.stringify(stringURLs));
}
- (void)_removeLocalDocumentURL:(CPURL)aURL
{
if (!window.localStorage)
return;
[_localDocumentURLs removeObject:aURL];
localStorage.setItem(CPDocumentControllerLocalDocumentURLsKey, JSON.stringify([self allObjects]));
}
- (CPSet)localDocumentURLs
{
return [_localDocumentURLs copy];
}
@end
+55 -4
View File
@@ -50,7 +50,7 @@ var CPViewControllerCachedCibs;
CPView _view; CPView _view;
id _representedObject @accessors(property=representedObject); id _representedObject @accessors(property=representedObject);
CPString _title @accessors(property=title); CPString _title;
CPString _cibName @accessors(property=cibName, readonly); CPString _cibName @accessors(property=cibName, readonly);
CPBundle _cibBundle @accessors(property=cibBundle, readonly); CPBundle _cibBundle @accessors(property=cibBundle, readonly);
@@ -78,7 +78,9 @@ var CPViewControllerCachedCibs;
- (id)initWithCibName:(CPString)aCibNameOrNil bundle:(CPBundle)aCibBundleOrNil owner:(id)anOwner - (id)initWithCibName:(CPString)aCibNameOrNil bundle:(CPBundle)aCibBundleOrNil owner:(id)anOwner
{ {
return [self initWithCibName:aCibNameOrNil bundle:aCibBundleOrNil externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner]]; return [self initWithCibName:aCibNameOrNil
bundle:aCibBundleOrNil
externalNameTable:[CPDictionary dictionaryWithObject:anOwner forKey:CPCibOwner]];
} }
/*! /*!
@@ -97,13 +99,34 @@ var CPViewControllerCachedCibs;
{ {
// Don't load the cib until someone actually requests the view. The user may just be intending to use setView:. // Don't load the cib until someone actually requests the view. The user may just be intending to use setView:.
_cibName = aCibNameOrNil; _cibName = aCibNameOrNil;
_cibBundle = aCibBundleOrNil || [CPBundle mainBundle]; _cibBundle = aCibBundleOrNil;
if (!_cibBundle)
{
var owner = [anExternalNameTable objectForKey:CPCibOwner];
_cibBundle = owner ? [CPBundle bundleForClass:[owner class]] : [CPBundle mainBundle];
}
_cibExternalNameTable = anExternalNameTable || [CPDictionary dictionaryWithObject:self forKey:CPCibOwner]; _cibExternalNameTable = anExternalNameTable || [CPDictionary dictionaryWithObject:self forKey:CPCibOwner];
} }
return self; return self;
} }
- (void)setTitle:(CPString)aTitle
{
_title = aTitle;
if (self._navigationItem)
[_navigationItem setTitle:aTitle];
}
- (CPString)title
{
return _title;
}
/*! /*!
Programmatically creates the view that the controller manages. Programmatically creates the view that the controller manages.
You should never call this method directly. The view controller calls this method when the view property is requested but is nil. You should never call this method directly. The view controller calls this method when the view property is requested but is nil.
@@ -124,9 +147,9 @@ var CPViewControllerCachedCibs;
// check if a cib is already cached for the current _cibName // check if a cib is already cached for the current _cibName
var cib = [CPViewControllerCachedCibs objectForKey:_cibName]; var cib = [CPViewControllerCachedCibs objectForKey:_cibName];
// If the cib isn't cached yet : fetch it and cache it
if (!cib) if (!cib)
{ {
// if the cib isn't cached yet : fetch it and cache it
cib = [[CPCib alloc] initWithContentsOfURL:[_cibBundle pathForResource:_cibName + @".cib"]]; cib = [[CPCib alloc] initWithContentsOfURL:[_cibBundle pathForResource:_cibName + @".cib"]];
[CPViewControllerCachedCibs setObject:cib forKey:_cibName]; [CPViewControllerCachedCibs setObject:cib forKey:_cibName];
} }
@@ -192,6 +215,34 @@ var CPViewControllerCachedCibs;
_view = aView; _view = aView;
} }
- (CPNavigationItem)navigationItem
{
var navigationItem = self._navigationItem;
if (!navigationItem)
navigationItem = [[CPNavigationItem alloc] initWithTitle:[self title]];
self._navigationItem = navigationItem;
return navigationItem;
}
- (void)viewWillAppear:(BOOL)isAnimated
{
}
- (void)viewDidAppear:(BOOL)isAnimated
{
}
- (void)viewWillDisappear:(BOOL)isAnimated
{
}
- (void)viewDidDisappear:(BOOL)isAnimated
{
}
@end @end
+57 -2
View File
@@ -177,7 +177,8 @@ CFHTTPRequest.prototype.responseText = function()
CFHTTPRequest.prototype.setRequestHeader = function(/*String*/ aHeader, /*Object*/ aValue) CFHTTPRequest.prototype.setRequestHeader = function(/*String*/ aHeader, /*Object*/ aValue)
{ {
return this._nativeRequest.setRequestHeader(aHeader, aValue); if (!this._URL)
return this._nativeRequest.setRequestHeader(aHeader, aValue);
} }
CFHTTPRequest.prototype.getResponseHeader = function(/*String*/ aHeader) CFHTTPRequest.prototype.getResponseHeader = function(/*String*/ aHeader)
@@ -198,11 +199,65 @@ CFHTTPRequest.prototype.overrideMimeType = function(/*String*/ aMimeType)
CFHTTPRequest.prototype.open = function(/*String*/ aMethod, /*String*/ aURL, /*Boolean*/ isAsynchronous, /*String*/ aUser, /*String*/ aPassword) CFHTTPRequest.prototype.open = function(/*String*/ aMethod, /*String*/ aURL, /*Boolean*/ isAsynchronous, /*String*/ aUser, /*String*/ aPassword)
{ {
return this._nativeRequest.open(aMethod, aURL, isAsynchronous, aUser, aPassword); aURL = makeAbsoluteURL(aURL);
if (aURL.isStorageURL())
{
this._URL = aURL;
this._method = aMethod;
this._isAsynchronous = isAsynchronous;
return;
}
else if (this._URL)
{
delete this._URL;
delete this._method;
delete this._isAsynchronous;
}
return this._nativeRequest.open(aMethod, aURL + "", isAsynchronous, aUser, aPassword);
}
function sendStorage(/*CFHTTPRequest*/ aRequest, /*String*/ aBody)
{
var method = aRequest._method.toUpperCase(),
eventDispatcher = aRequest._eventDispatcher;
if (method === "GET")
{
var item = localStorage.getItem(aRequest._URL);
if (item === undefined)
eventDispatcher.dispatchEvent({ type:"failure", request:aRequest });
else
eventDispatcher.dispatchEvent({ type:"success", request:aRequest });
}
else if (method === "POST" || method === "PUT")
{
try
{
localStorage.setItem(aRequest._URL, aBody);
eventDispatcher.dispatchEvent({ type:"success", request:aRequest });
}
catch (anException)
{
eventDispatcher.dispatchEvent({ type:"failure", request:aRequest });
}
}
else
eventDispatcher.dispatchEvent({ type:"failure", request:aRequest });
} }
CFHTTPRequest.prototype.send = function(/*Object*/ aBody) CFHTTPRequest.prototype.send = function(/*Object*/ aBody)
{ {
if (this._URL)
return sendStorage(this, aBody);
try try
{ {
return this._nativeRequest.send(aBody); return this._nativeRequest.send(aBody);
+21
View File
@@ -498,6 +498,27 @@ CFURL.prototype.authority = function()
DISPLAY_NAME(CFURL.prototype.authority); DISPLAY_NAME(CFURL.prototype.authority);
CFURL.prototype.isStorageURL = function()
{
return this.isLocalStorageURL() || this.isSessionStorageURL();
}
DISPLAY_NAME(CFURL.prototype.isStorageURL);
CFURL.prototype.isLocalStorageURL = function()
{
return this.scheme() === "storage.local";
}
DISPLAY_NAME(CFURL.prototype.isLocalStorageURL);
CFURL.prototype.isSessionStorageURL = function()
{
return this.scheme() === "storage.session";
}
DISPLAY_NAME(CFURL.prototype.isSessionStorageURL);
CFURL.prototype.hasDirectoryPath = function() CFURL.prototype.hasDirectoryPath = function()
{ {
var hasDirectoryPath = this._hasDirectoryPath; var hasDirectoryPath = this._hasDirectoryPath;