Permalink
Browse files

Initial Commit

  • Loading branch information...
0 parents commit 5c65bf365da1e791348700966575ebcb9ff3ba45 @Me1000 committed Feb 2, 2010
Showing with 372 additions and 0 deletions.
  1. +67 −0 AppController.j
  2. +12 −0 Info.plist
  3. +38 −0 Jakefile
  4. +1 −0 README
  5. +79 −0 RLOfflineDataStore.j
  6. BIN Resources/spinner.gif
  7. +86 −0 index-debug.html
  8. +71 −0 index.html
  9. +18 −0 main.j
@@ -0,0 +1,67 @@
+/*
+ * AppController.j
+ * dbstore
+ *
+ * Created by You on February 2, 2010.
+ * Copyright 2010, Your Company All rights reserved.
+ */
+
+@import <Foundation/CPObject.j>
+@import "RLOfflineDataStore.j"
+
+
+@implementation AppController : CPObject
+{
+ id dataStorage;
+ CPButton aButton;
+ CPTextField label;
+}
+
+- (void)applicationDidFinishLaunching:(CPNotification)aNotification
+{
+ var theWindow = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask],
+ contentView = [theWindow contentView];
+
+ label = [[CPTextField alloc] initWithFrame:CGRectMakeZero()];
+
+ [label setStringValue:@""];
+ [label setFont:[CPFont boldSystemFontOfSize:24.0]];
+
+ [label sizeToFit];
+
+ [label setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin | CPViewMinYMargin | CPViewMaxYMargin];
+ [label setCenter:[contentView center]];
+
+ [contentView addSubview:label];
+
+ [theWindow orderFront:self];
+
+ // Uncomment the following line to turn on the standard menu bar.
+ //[CPMenu setMenuBarVisible:YES];
+
+ dataStorage = [[RLOfflineDataStore alloc] initWithName:@"HelloWorld" delegate:self];
+ //[dataStorage setValue:@"World" forKey:@"word1"];
+ [dataStorage getValueForKey:@"HelloWorldTestApp"];
+
+ //[dataStorage removeValueForKey:@"word1"];
+
+ aButton = [[CPSlider alloc] initWithFrame:CGRectMake(100,100,100,24)];
+ [aButton setTarget:self];
+ [aButton setAction:@selector(setNewValue:)];
+ [contentView addSubview:aButton];
+}
+
+- (void)didReciveData:(CPString)aString
+{
+ [aButton setIntValue:aString];
+ [label setStringValue:aString];
+ [label sizeToFit];
+}
+
+- (void)setNewValue:(id)sender
+{
+ [dataStorage setValue:[sender intValue] forKey:@"HelloWorldTestApp"];
+ [label setStringValue:[sender intValue]];
+ [label sizeToFit];
+}
+@end
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CPApplicationDelegateClass</key>
+ <string>AppController</string>
+ <key>CPBundleName</key>
+ <string>dbstore</string>
+ <key>CPPrincipalClass</key>
+ <string>CPApplication</string>
+</dict>
+</plist>
@@ -0,0 +1,38 @@
+/*
+ * Jakefile
+ * dbstore
+ *
+ * Created by You on February 2, 2010.
+ * Copyright 2010, Your Company All rights reserved.
+ */
+
+var ENV = require("system").env,
+ FILE = require("file"),
+ task = require("jake").task,
+ FileList = require("jake").FileList,
+ app = require("cappuccino/jake").app,
+ configuration = ENV["CONFIG"] || ENV["CONFIGURATION"] || ENV["c"] || "Debug";
+
+app ("dbstore", function(task)
+{
+ task.setBuildIntermediatesPath(FILE.join("Build", "dbstore.build", configuration));
+ task.setBuildPath(FILE.join("Build", configuration));
+
+ task.setProductName("dbstore");
+ task.setIdentifier("com.yourcompany.dbstore");
+ task.setVersion("1.0");
+ task.setAuthor("Your Company");
+ task.setEmail("feedback @nospam@ yourcompany.com");
+ task.setSummary("dbstore");
+ task.setSources(new FileList("**/*.j"));
+ task.setResources(new FileList("Resources/*"));
+ task.setIndexFilePath("index.html");
+ task.setInfoPlistPath("Info.plist");
+
+ if (configuration === "Debug")
+ task.setCompilerFlags("-DDEBUG -g");
+ else
+ task.setCompilerFlags("-O");
+});
+
+task ("default", ["dbstore"]);
1 README
@@ -0,0 +1 @@
+This is a simple Cappuccino implementation of html5 offline data storage. Feel free to fork it and do whatever.
@@ -0,0 +1,79 @@
+@implementation RLOfflineDataStore : CPObject
+{
+ CPString _name;
+ double _size;
+ id _db;
+ id _delegate;
+}
+
++ (BOOL)offlineDataStoreIsAvailable
+{
+ return !!window.openDatabase
+}
+
+- (id)initWithName:(CPString)aName delegate:(id)anObject
+{
+ _delegate = anObject;
+
+ if ([RLOfflineDataStore offlineDataStoreIsAvailable])
+ [CPException exceptionWithName:@"RLOfflineDataStore" reason:@"Offline storage is not supported for this browser." userInfo:nil];
+
+ self = [super init];
+ if (self)
+ {
+ _name = aName;
+ _size = 1024 * 2000;
+
+ _db = openDatabase('RCOfflineDataStore-' + _name, '1.0', _name, _size);
+
+ if(!_db && [_delegate respondsToSelector:@selector(userDidRejectDatabase)])
+ [_delegate userDidRejectDatabase];
+ else if(!_db)
+ [CPException exceptionWithName:@"RLOfflineDataStore" reason:@"Offline storage was rejected by the user." userInfo:nil];
+
+ _db.transaction(function(_db){
+ _db.executeSql( 'CREATE TABLE IF NOT EXISTS RLOfflineDataStore (key TEXT UNIQUE NOT NULL PRIMARY KEY, value TEXT NOT NULL)' );
+ });
+ }
+ return self;
+}
+
+- (void)setValue:(CPString)aValue forKey:(CPString)aKey
+{
+ //there is probably a better way to do this
+ _db.transaction(function(db){
+ //if the key exists update it, if not it will fail quietly.
+ db.executeSql("UPDATE RLOfflineDataStore SET value = ? WHERE key = ?",[aValue, aKey], function result(tx, rs){}, function anError(tx, err){});
+ //if the key exists this will fail quietyl, if not it will add the key to the db.
+ db.executeSql("INSERT INTO RLOfflineDataStore (key, value) VALUES (?, ?)", [aKey, aValue], function result(db, rs){}, function error(db, err){});
+ });
+
+
+}
+
+- (void)getValueForKey:(CPString)aKey
+{
+ _db.transaction(function(db){
+ db.executeSql("SELECT value FROM RLOfflineDataStore WHERE key=?",[aKey], function result(text, result){[self _parseResults:result];}, function anError(text, theError){});
+ });
+}
+
+- (void)removeValueForKey:(CPString)aKey
+{
+ _db.transaction(function(db){
+ db.executeSql("DELETE FROM RLOfflineDataStore WHERE key=?",[aKey], function result(text, result){}, function anError(text, theError){});
+ });
+
+}
+
+- (void)_parseResults:(id)results
+{
+ if(results.rows.length > 0)
+ var returnValue = results.rows.item(0).value;
+ else
+ var returnValue = nil;
+
+ [_delegate didReciveData:returnValue];
+}
+
+@end
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns = "http://www.w3.org/1999/xhtml" xml:lang = "en" lang = "en">
+<!--
+ index-debug.html
+ dbstore
+
+ Created by You on February 2, 2010.
+ Copyright 2010, Your Company All rights reserved.
+-->
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
+
+ <title>dbstore</title>
+
+ <script type = "text/javascript">
+ OBJJ_MAIN_FILE = "main.j";
+ OBJJ_INCLUDE_PATHS = ["Frameworks/Debug", "Frameworks", "SomethingElse"];
+ </script>
+
+ <script src = "Frameworks/Debug/Objective-J/Objective-J.js" type = "text/javascript"></script>
+
+ <script type = "text/javascript">
+ objj_msgSend_reset();
+
+ // DEBUG OPTIONS:
+
+ // Uncomment to enable printing of backtraces on exceptions:
+ //objj_msgSend_decorate(objj_backtrace_decorator);
+
+ // Uncomment to enable runtime type checking:
+ //objj_msgSend_decorate(objj_typecheck_decorator);
+
+ // Uncomment (along with both above) to print backtraces on type check errors:
+ //objj_typecheck_prints_backtrace = true;
+ </script>
+
+ <style type = "text/css">
+ body{margin:0; padding:0;}
+ #container {position: absolute; top:50%; left:50%;}
+ #content {width:800px; text-align:center; margin-left: -400px; height:50px; margin-top:-25px; line-height: 50px;}
+ #content {font-family: "Helvetica", "Arial", sans-serif; font-size: 18px; color: black; text-shadow: 0px 1px 0px white; }
+ #loadgraphic {margin-right: 0.2em; margin-bottom:-2px;}
+ </style>
+
+ <!--[if lt IE 7]>
+ <STYLE type="text/css">
+ #container { position: relative; top: 50%; }
+ #content { position: relative;}
+ </STYLE>
+ <![endif]-->
+
+ </head>
+
+ <body style="">
+ <div id="cappuccino-body">
+ <div id="loadingcontainer" style=" background-color: #eeeeee; overflow:hidden; width:100%; height:100%; position: absolute; top: 0; left: 0;">
+ <script type = "text/javascript">
+ document.write("<div id='container'><p id='content'>" +
+ "<img id='loadgraphic' width='16' height='16' src='Resources/spinner.gif' /> " +
+ "Loading dbstore...</p></div>");
+ </script>
+
+ <noscript>
+ <div id="container">
+ <div style="width: 440px; padding: 10px 25px 20px 25px; font-family: sans-serif; background-color: #ffffff; position: relative; left: -245px; top: -120px; text-align: center; -moz-border-radius: 20px; -webkit-border-radius: 20px; color: #555555">
+ <p style="line-height: 1.4em;">JavaScript is required for this site to work correctly but is either disabled or not supported by your browser.</p>
+ <p style="font-size:120%; padding:10px;"><a href="http://cappuccino.org/noscript">Show me how to enable JavaScript</a></p>
+ <p style="font-size:80%;">You may want to upgrade to a newer browser while you're at it:</p>
+ <ul style="margin:0;padding:0; text-align: center; font-size:80%;" >
+ <li style="display: inline;"><a href="http://www.apple.com/safari/download/">Safari</a></li>
+ <li style="display: inline;"><a href="http://www.mozilla.com/en-US/firefox/">Firefox</a></li>
+ <li style="display: inline;"><a href="http://www.google.com/chrome/">Chrome</a></li>
+ <li style="display: inline;"><a href="http://www.opera.com/download/">Opera</a></li>
+ <li style="display: inline;"><a href="http://www.microsoft.com/windows/downloads/ie/getitnow.mspx">Internet Explorer</a></li>
+ </ul>
+ </div>
+ </div>
+ </noscript>
+ </div>
+ </div>
+ </body>
+
+</html>
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns = "http://www.w3.org/1999/xhtml" xml:lang = "en" lang = "en">
+<!--
+ index.html
+ dbstore
+
+ Created by You on February 2, 2010.
+ Copyright 2010, Your Company All rights reserved.
+-->
+ <head>
+ <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
+
+ <title>dbstore</title>
+
+ <script type = "text/javascript">
+ OBJJ_MAIN_FILE = "main.j";
+ </script>
+
+ <script src = "Frameworks/Objective-J/Objective-J.js" type = "text/javascript"></script>
+
+ <style type = "text/css">
+ body{margin:0; padding:0;}
+ #container {position: absolute; top:50%; left:50%;}
+ #content {width:800px; text-align:center; margin-left: -400px; height:50px; margin-top:-25px; line-height: 50px;}
+ #content {font-family: "Helvetica", "Arial", sans-serif; font-size: 18px; color: black; text-shadow: 0px 1px 0px white; }
+ #loadgraphic {margin-right: 0.2em; margin-bottom:-2px;}
+ </style>
+
+ <!--[if lt IE 7]>
+ <STYLE type="text/css">
+ #container { position: relative; top: 50%; }
+ #content { position: relative;}
+ </STYLE>
+ <![endif]-->
+
+ </head>
+
+ <body style="">
+ <div id="cappuccino-body">
+ <div id="loadingcontainer" style=" background-color: #eeeeee; overflow:hidden; width:100%; height:100%; position: absolute; top: 0; left: 0;">
+ <script type = "text/javascript">
+ document.write("<div id='container'><p id='content'>" +
+ "<img id='loadgraphic' width='16' height='16' src='Resources/spinner.gif' /> " +
+ "Loading dbstore...</p></div>");
+ </script>
+
+ <noscript>
+ <div id="container">
+ <div style="width: 440px; padding: 10px 25px 20px 25px; font-family: sans-serif; background-color: #ffffff; position: relative; left: -245px; top: -120px; text-align: center; -moz-border-radius: 20px; -webkit-border-radius: 20px; color: #555555">
+ <p style="line-height: 1.4em;">JavaScript is required for this site to work correctly but is either disabled or not supported by your browser.</p>
+ <p style="font-size:120%; padding:10px;"><a href="http://cappuccino.org/noscript">Show me how to enable JavaScript</a></p>
+ <p style="font-size:80%;">You may want to upgrade to a newer browser while you're at it:</p>
+ <ul style="margin:0;padding:0; text-align: center; font-size:80%;" >
+ <li style="display: inline;"><a href="http://www.apple.com/safari/download/">Safari</a></li>
+ <li style="display: inline;"><a href="http://www.mozilla.com/en-US/firefox/">Firefox</a></li>
+ <li style="display: inline;"><a href="http://www.google.com/chrome/">Chrome</a></li>
+ <li style="display: inline;"><a href="http://www.opera.com/download/">Opera</a></li>
+ <li style="display: inline;"><a href="http://www.microsoft.com/windows/downloads/ie/getitnow.mspx">Internet Explorer</a></li>
+ </ul>
+ </div>
+ </div>
+ </noscript>
+ </div>
+ </div>
+ </body>
+
+</html>
+
18 main.j
@@ -0,0 +1,18 @@
+/*
+ * AppController.j
+ * dbstore
+ *
+ * Created by You on February 2, 2010.
+ * Copyright 2010, Your Company All rights reserved.
+ */
+
+@import <Foundation/Foundation.j>
+@import <AppKit/AppKit.j>
+
+@import "AppController.j"
+
+
+function main(args, namedArgs)
+{
+ CPApplicationMain(args, namedArgs);
+}

2 comments on commit 5c65bf3

if ([RLOfflineDataStore offlineDataStoreIsAvailable]) shouldn't that be negated?

Owner

Me1000 replied Feb 2, 2010

No, there are two happenings here.

That one checks browser compatibility,
The next checks if the user actually allowed the db to be created.

Like I said, I'm sure there are better ways to work with most of this, but it worked well enough for my needs.
I actually think that should try to notify a delegate before trowing the exception, diving the developer a more graceful way to handle it.

Please sign in to comment.