mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-09-09 12:17:13 +00:00
Compare commits
2
Commits
@each
...
localStorage
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4091acd0ec | ||
|
|
f8114b0760 |
+17
-4
@@ -210,10 +210,10 @@ var CPDocumentUntitledCount = 0;
|
||||
@throws CPUnsupportedMethodException if this method hasn't been overriden by the subclass
|
||||
@return the document data
|
||||
*/
|
||||
- (CPData)dataOfType:(CPString)aType error:({CPError})anError
|
||||
- (CPData)dataOfType:(CPString)aType
|
||||
{
|
||||
[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
|
||||
{
|
||||
var data = [self dataOfType:[self fileType] error:nil],
|
||||
oldChangeCount = _changeCount;
|
||||
if (anAbsoluteURL.isLocalStorageURL())
|
||||
[[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];
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ var CPSharedDocumentController = nil;
|
||||
{
|
||||
CPArray _documents;
|
||||
CPArray _documentTypes;
|
||||
CPArray _localDocumentURLs;
|
||||
}
|
||||
|
||||
/*!
|
||||
@@ -59,14 +60,30 @@ var CPSharedDocumentController = nil;
|
||||
- (id)init
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
|
||||
if (self)
|
||||
{
|
||||
_documents = [[CPArray alloc] init];
|
||||
|
||||
if (!CPSharedDocumentController)
|
||||
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"];
|
||||
}
|
||||
return self;
|
||||
@@ -219,7 +236,7 @@ var CPSharedDocumentController = nil;
|
||||
Opens a new document in the application.
|
||||
@param aSender the requesting object
|
||||
*/
|
||||
- (CFAction)newDocument:(id)aSender
|
||||
- (@action)newDocument:(id)aSender
|
||||
{
|
||||
[self openUntitledDocumentOfType:[[_documentTypes objectAtIndex:0] objectForKey:@"CPBundleTypeName"] display:YES];
|
||||
}
|
||||
@@ -455,3 +472,41 @@ var CPSharedDocumentController = nil;
|
||||
}
|
||||
|
||||
@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
|
||||
|
||||
@@ -50,7 +50,7 @@ var CPViewControllerCachedCibs;
|
||||
CPView _view;
|
||||
|
||||
id _representedObject @accessors(property=representedObject);
|
||||
CPString _title @accessors(property=title);
|
||||
CPString _title;
|
||||
|
||||
CPString _cibName @accessors(property=cibName, readonly);
|
||||
CPBundle _cibBundle @accessors(property=cibBundle, readonly);
|
||||
@@ -78,7 +78,9 @@ var CPViewControllerCachedCibs;
|
||||
|
||||
- (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:.
|
||||
_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];
|
||||
}
|
||||
|
||||
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.
|
||||
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
|
||||
var cib = [CPViewControllerCachedCibs objectForKey:_cibName];
|
||||
|
||||
// If the cib isn't cached yet : fetch it and cache it
|
||||
if (!cib)
|
||||
{
|
||||
// if the cib isn't cached yet : fetch it and cache it
|
||||
cib = [[CPCib alloc] initWithContentsOfURL:[_cibBundle pathForResource:_cibName + @".cib"]];
|
||||
[CPViewControllerCachedCibs setObject:cib forKey:_cibName];
|
||||
}
|
||||
@@ -192,6 +215,34 @@ var CPViewControllerCachedCibs;
|
||||
_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
|
||||
|
||||
|
||||
|
||||
@@ -177,7 +177,8 @@ CFHTTPRequest.prototype.responseText = function()
|
||||
|
||||
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)
|
||||
@@ -198,11 +199,65 @@ CFHTTPRequest.prototype.overrideMimeType = function(/*String*/ aMimeType)
|
||||
|
||||
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)
|
||||
{
|
||||
if (this._URL)
|
||||
return sendStorage(this, aBody);
|
||||
|
||||
try
|
||||
{
|
||||
return this._nativeRequest.send(aBody);
|
||||
|
||||
@@ -498,6 +498,27 @@ CFURL.prototype.authority = function()
|
||||
|
||||
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()
|
||||
{
|
||||
var hasDirectoryPath = this._hasDirectoryPath;
|
||||
|
||||
Reference in New Issue
Block a user