Skip to content
Browse files

Adding all files

  • Loading branch information...
1 parent 96c1cfd commit 67178e514ae6cafe1d9b3ec75493e9978655cc52 @rcorral committed Nov 1, 2011
View
2 .gitignore
@@ -0,0 +1,2 @@
+www/assets/js/my.conf.js
+.DS_Store
View
197 www/assets/css/customSwatch.css
@@ -0,0 +1,197 @@
+/* @override http://localhost/joomla-app/www/assets/css/customSwatch.css */
+
+#logo {
+ position: absolute;
+ left: 10px;
+ top: -1px;
+ margin: 0;
+ padding: 0;
+ text-indent: -9999px;
+ width: 63px;
+ height: 46px; background-image: url(../images/logo.png);
+ z-index: 9999;
+ -webkit-box-shadow: 0 0 3px rgba(0,0,0,.7);
+ box-shadow: 0 0 3px rgba(0,0,0,.7);
+}
+
+span.item-published, span.item-enabled { color: #00690f; }
+span.item-unpublished { color: #999; }
+span.item-registered { color: #d10d0e; }
+span.item-public, span.item-active { color: #1b1aab; }
+
+span.gray-text { color: #999; font-weight: bold; }
+
+.ui-bar-b { }
+
+.ui-btn-corner-all { border-radius: 3px; }
+
+.ui-bar-a { border: 1px solid #2a2a2a; background: #111; color: #fff; font-weight: bold; text-shadow: 0 -1px 1px #000; background-image: -webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#111)); background-image: -webkit-linear-gradient(top,#3c3c3c,#111); background-image: -moz-linear-gradient(top,#3c3c3c,#111); background-image: -ms-linear-gradient(top,#3c3c3c,#111); background-image: -o-linear-gradient(top,#3c3c3c,#111); background-image: linear-gradient(top,#3c3c3c,#111) }
+
+.ui-bar-a,.ui-bar-a input,.ui-bar-a select,.ui-bar-a textarea,.ui-bar-a button { font-family: Helvetica,Arial,sans-serif }
+
+.ui-bar-a .ui-link-inherit { color: #fff }
+
+.ui-bar-a .ui-link { color: #7cc4e7; font-weight: bold }
+
+.ui-body-a { border: 1px solid #2a2a2a; background: #222; color: #fff; text-shadow: 0 1px 0 #000; font-weight: normal; background-image: -webkit-gradient(linear,left top,left bottom,from(#666),to(#222)); background-image: -webkit-linear-gradient(top,#666,#222); background-image: -moz-linear-gradient(top,#666,#222); background-image: -ms-linear-gradient(top,#666,#222); background-image: -o-linear-gradient(top,#666,#222); background-image: linear-gradient(top,#666,#222) }
+
+.ui-body-a,.ui-body-a input,.ui-body-a select,.ui-body-a textarea,.ui-body-a button { font-family: Helvetica,Arial,sans-serif }
+
+.ui-body-a .ui-link-inherit { color: #fff }
+
+.ui-body-a .ui-link { color: #2489ce; font-weight: bold }
+
+.ui-br { border-bottom: 1px solid #e4dfd4; }
+
+div.ui-field-contain.ui-body.ui-br { padding: 5px 0 10px !important; }
+
+.ui-btn-up-a { border: 1px solid #222; background: #333; font-weight: bold; color: #fff; text-shadow: 0 -1px 1px #000; background-image: -webkit-gradient(linear,left top,left bottom,from(#555),to(#333)); background-image: -webkit-linear-gradient(top,#555,#333); background-image: -moz-linear-gradient(top,#555,#333); background-image: -ms-linear-gradient(top,#555,#333); background-image: -o-linear-gradient(top,#555,#333); background-image: linear-gradient(top,#555,#333) }
+
+.ui-btn-up-a a.ui-link-inherit { color: #fff }
+
+.ui-btn-hover-a { border: 1px solid #000; background: #444; font-weight: bold; color: #fff; text-shadow: 0 -1px 1px #000; background-image: -webkit-gradient(linear,left top,left bottom,from(#666),to(#444)); background-image: -webkit-linear-gradient(top,#666,#444); background-image: -moz-linear-gradient(top,#666,#444); background-image: -ms-linear-gradient(top,#666,#444); background-image: -o-linear-gradient(top,#666,#444); background-image: linear-gradient(top,#666,#444) }
+
+.ui-btn-hover-a a.ui-link-inherit { color: #fff }
+
+.ui-btn-down-a { border: 1px solid #000; background: #3d3d3d; font-weight: bold; color: #fff; text-shadow: 0 -1px 1px #000; background-image: -webkit-gradient(linear,left top,left bottom,from(#333),to(#5a5a5a)); background-image: -webkit-linear-gradient(top,#333,#5a5a5a); background-image: -moz-linear-gradient(top,#333,#5a5a5a); background-image: -ms-linear-gradient(top,#333,#5a5a5a); background-image: -o-linear-gradient(top,#333,#5a5a5a); background-image: linear-gradient(top,#333,#5a5a5a) }
+
+.ui-btn-down-a a.ui-link-inherit { color: #fff }
+
+.ui-btn-up-a,.ui-btn-hover-a,.ui-btn-down-a { font-family: Helvetica,Arial,sans-serif; text-decoration: none }
+
+.ui-bar-b { border: 1px solid #222; background: #312f30; color: #fff; font-weight: bold; text-shadow: 0 -1px 1px #254f7a; background-image: -webkit-gradient(linear,left top,left bottom,from(#494748),to(#312f30)); background-image: -webkit-linear-gradient(top,#494748,#312f30); background-image: -moz-linear-gradient(top,#494748,#312f30); background-image: -ms-linear-gradient(top,#494748,#312f30); background-image: -o-linear-gradient(top,#494748,#312f30); background-image: linear-gradient(top,#494748,#312f30) }
+
+.ui-bar-b,.ui-bar-b input,.ui-bar-b select,.ui-bar-b textarea,.ui-bar-b button { font-family: Helvetica,Arial,sans-serif }
+
+.ui-bar-b .ui-link-inherit { color: #fff }
+
+.ui-bar-b .ui-link { color: #7cc4e7; font-weight: bold }
+
+.ui-body-b { border: 1px solid #c6c6c6; background: #ccc; color: #333; text-shadow: 0 1px 0 #fff; font-weight: normal; background-image: -webkit-gradient(linear,left top,left bottom,from(#e6e6e6),to(#ccc)); background-image: -webkit-linear-gradient(top,#e6e6e6,#ccc); background-image: -moz-linear-gradient(top,#e6e6e6,#ccc); background-image: -ms-linear-gradient(top,#e6e6e6,#ccc); background-image: -o-linear-gradient(top,#e6e6e6,#ccc); background-image: linear-gradient(top,#e6e6e6,#ccc) }
+
+.ui-body-b,.ui-body-b input,.ui-body-b select,.ui-body-b textarea,.ui-body-b button { font-family: Helvetica,Arial,sans-serif }
+
+.ui-body-b .ui-link-inherit { color: #333 }
+
+.ui-body-b .ui-link { color: #2489ce; font-weight: bold }
+
+.ui-btn-up-b { border: 1px solid #222; background: #eee; font-weight: bold; color: #eee; text-shadow: 0 -1px 1px #111; background-image: -webkit-gradient(linear,left top,left bottom,from(#333),to(#000)); background-image: -webkit-linear-gradient(top,#333,#000); background-image: -moz-linear-gradient(top,#fff,#000); background-image: -ms-linear-gradient(top,#333,#000); background-image: -o-linear-gradient(top,#333,#000); background-image: linear-gradient(top,#333,#000) }
+
+.ui-btn-up-b a.ui-link-inherit { color: #fff }
+
+.ui-btn-hover-b { border: 1px solid #333; background: #000; font-weight: bold; color: #fff; text-shadow: 0 -1px 1px #000; background-image: -webkit-gradient(linear,left top,left bottom,from(#111),to(#000)); background-image: -webkit-linear-gradient(top,#111,#000); background-image: -moz-linear-gradient(top,#111,#000); background-image: -ms-linear-gradient(top,#111,#000); background-image: -o-linear-gradient(top,#111,#000); background-image: linear-gradient(top,#111,#000) }
+
+.ui-btn-hover-b a.ui-link-inherit { color: #fff }
+
+.ui-btn-down-b { border: 1px solid #000; background: #444; font-weight: bold; color: #fff; text-shadow: 0 -1px 1px #000; background-image: -webkit-gradient(linear,left top,left bottom,from(#555),to(#444)); background-image: -webkit-linear-gradient(top,#555,#444); background-image: -moz-linear-gradient(top,#555,#444); background-image: -ms-linear-gradient(top,#555,#444); background-image: -o-linear-gradient(top,#555,#444); background-image: linear-gradient(top,#555,#444) }
+
+.ui-btn-down-b a.ui-link-inherit { color: #fff }
+
+.ui-btn-up-b,.ui-btn-hover-b,.ui-btn-down-b { font-family: Helvetica,Arial,sans-serif; text-decoration: none }
+
+.ui-bar-c { border: none !important; background: #222; color: #3e3e3e; font-weight: bold; text-shadow: 0 1px 1px #fff; background-image: -webkit-gradient(linear,left top,left bottom,from(#444),to(#222)); background-image: -webkit-linear-gradient(top,#444,#222); background-image: -moz-linear-gradient(top,#444,#222); background-image: -ms-linear-gradient(top,#444,#222); background-image: -o-linear-gradient(top,#444,#222); background-image: linear-gradient(top,#444,#222) }
+
+.ui-bar-c,.ui-bar-c input,.ui-bar-c select,.ui-bar-c textarea,.ui-bar-c button { font-family: Helvetica,Arial,sans-serif }
+
+.ui-body-c { border: 1px solid #b3b3b3; color: #333; text-shadow: 0 1px 0 #fff; background: #f3ede1; background-image: -webkit-gradient(linear,left top,left bottom,from(#f2ece0),to(#ddd)); background-image: -webkit-linear-gradient(top,#f2ece0,#f3ede1); background-image: -moz-linear-gradient(top,#f2ece0,#f3ede1); background-image: -ms-linear-gradient(top,#f2ece0,#f3ede1); background-image: -o-linear-gradient(top,#f2ece0,#f3ede1); background-image: linear-gradient(top,#f2ece0,#f3ede1) }
+
+.ui-body-c,.ui-body-c input,.ui-body-c select,.ui-body-c textarea,.ui-body-c button { font-family: Helvetica,Arial,sans-serif }
+
+.ui-body-c .ui-link-inherit { color: #333 }
+
+.ui-body-c .ui-link { color: #2489ce; font-weight: bold }
+
+.ui-btn-up-c { border: 1px solid #ccc; background: #eee; font-weight: bold; color: #444; text-shadow: 0 1px 1px #f6f6f6; background-image: -webkit-gradient(linear,left top,left bottom,from(#fdfdfd),to(#eee)); background-image: -webkit-linear-gradient(top,#fdfdfd,#eee); background-image: -moz-linear-gradient(top,#fdfdfd,#eee); background-image: -ms-linear-gradient(top,#fdfdfd,#eee); background-image: -o-linear-gradient(top,#fdfdfd,#eee); background-image: linear-gradient(top,#fdfdfd,#eee) }
+
+.ui-btn-up-c a.ui-link-inherit { color: #2f3e46 }
+
+.ui-btn-hover-c { border: 1px solid #bbb; background: #dadada; font-weight: bold; color: #101010; text-shadow: 0 1px 1px #fff; background-image: -webkit-gradient(linear,left top,left bottom,from(#ededed),to(#dadada)); background-image: -webkit-linear-gradient(top,#ededed,#dadada); background-image: -moz-linear-gradient(top,#ededed,#dadada); background-image: -ms-linear-gradient(top,#ededed,#dadada); background-image: -o-linear-gradient(top,#ededed,#dadada); background-image: linear-gradient(top,#ededed,#dadada) }
+
+.ui-btn-hover-c a.ui-link-inherit { color: #2f3e46 }
+
+.ui-btn-down-c a.ui-link-inherit { color: #2f3e46 }
+
+.ui-btn-up-c,.ui-btn-hover-c,.ui-btn-down-c { font-family: Helvetica,Arial,sans-serif; text-decoration: none }
+
+.ui-bar-d { border: 1px solid #ccc; background: #bbb; color: #333; text-shadow: 0 1px 0 #eee; background-image: -webkit-gradient(linear,left top,left bottom,from(#ddd),to(#bbb)); background-image: -webkit-linear-gradient(top,#ddd,#bbb); background-image: -moz-linear-gradient(top,#ddd,#bbb); background-image: -ms-linear-gradient(top,#ddd,#bbb); background-image: -o-linear-gradient(top,#ddd,#bbb); background-image: linear-gradient(top,#ddd,#bbb) }
+
+.ui-bar-d,.ui-bar-d input,.ui-bar-d select,.ui-bar-d textarea,.ui-bar-d button { font-family: Helvetica,Arial,sans-serif }
+
+.ui-bar-d .ui-link-inherit { color: #333 }
+
+.ui-bar-d .ui-link { color: #2489ce; font-weight: bold }
+
+.ui-body-d { border: 1px solid #ccc; color: #333; text-shadow: 0 1px 0 #fff; background: #fff }
+
+.ui-body-d,.ui-body-d input,.ui-body-d select,.ui-body-d textarea,.ui-body-d button { font-family: Helvetica,Arial,sans-serif }
+
+.ui-body-d .ui-link-inherit { color: #333 }
+
+.ui-body-d .ui-link { color: #2489ce; font-weight: bold }
+
+.ui-btn-up-d { border: 1px solid #ccc; background: #fff; font-weight: bold; color: #444; text-shadow: 0 1px 1px #fff }
+
+.ui-btn-up-d a.ui-link-inherit { color: #333 }
+
+.ui-btn-hover-d { border: 1px solid #aaa; background: #eee; font-weight: bold; color: #222; cursor: pointer; text-shadow: 0 1px 1px #fff; background-image: -webkit-gradient(linear,left top,left bottom,from(#fdfdfd),to(#eee)); background-image: -webkit-linear-gradient(top,#fdfdfd,#eee); background-image: -moz-linear-gradient(top,#fdfdfd,#eee); background-image: -ms-linear-gradient(top,#fdfdfd,#eee); background-image: -o-linear-gradient(top,#fdfdfd,#eee); background-image: linear-gradient(top,#fdfdfd,#eee) }
+
+.ui-btn-hover-d a.ui-link-inherit { color: #222 }
+
+.ui-btn-down-d { border: 1px solid #aaa; background: #fff; font-weight: bold; color: #111; text-shadow: 0 1px 1px #fff; background-image: -webkit-gradient(linear,left top,left bottom,from(#eee),to(#fff)); background-image: -webkit-linear-gradient(top,#eee,#fff); background-image: -moz-linear-gradient(top,#eee,#fff); background-image: -ms-linear-gradient(top,#eee,#fff); background-image: -o-linear-gradient(top,#eee,#fff); background-image: linear-gradient(top,#eee,#fff) }
+
+.ui-btn-down-d a.ui-link-inherit { color: #111 }
+
+.ui-btn-up-d,.ui-btn-hover-d,.ui-btn-down-d { font-family: Helvetica,Arial,sans-serif; text-decoration: none }
+
+.ui-bar-e { border: 1px solid #f7c942; background: #fadb4e; color: #333; text-shadow: 0 1px 0 #fff; background-image: -webkit-gradient(linear,left top,left bottom,from(#fceda7),to(#fadb4e)); background-image: -webkit-linear-gradient(top,#fceda7,#fadb4e); background-image: -moz-linear-gradient(top,#fceda7,#fadb4e); background-image: -ms-linear-gradient(top,#fceda7,#fadb4e); background-image: -o-linear-gradient(top,#fceda7,#fadb4e); background-image: linear-gradient(top,#fceda7,#fadb4e) }
+
+.ui-bar-e,.ui-bar-e input,.ui-bar-e select,.ui-bar-e textarea,.ui-bar-e button { font-family: Helvetica,Arial,sans-serif }
+
+.ui-bar-e .ui-link-inherit { color: #333 }
+
+.ui-bar-e .ui-link { color: #2489ce; font-weight: bold }
+
+.ui-body-e { border: 1px solid #f7c942; color: #333; text-shadow: 0 1px 0 #fff; background: #faeb9e; background-image: -webkit-gradient(linear,left top,left bottom,from(#fff),to(#faeb9e)); background-image: -webkit-linear-gradient(top,#fff,#faeb9e); background-image: -moz-linear-gradient(top,#fff,#faeb9e); background-image: -ms-linear-gradient(top,#fff,#faeb9e); background-image: -o-linear-gradient(top,#fff,#faeb9e); background-image: linear-gradient(top,#fff,#faeb9e) }
+
+.ui-body-e,.ui-body-e input,.ui-body-e select,.ui-body-e textarea,.ui-body-e button { font-family: Helvetica,Arial,sans-serif }
+
+.ui-body-e .ui-link-inherit { color: #333 }
+
+.ui-body-e .ui-link { color: #2489ce; font-weight: bold }
+
+.ui-btn-up-e { border: 1px solid #f7c942; background: #fadb4e; font-weight: bold; color: #333; text-shadow: 0 1px 0 #fff; background-image: -webkit-gradient(linear,left top,left bottom,from(#fceda7),to(#fadb4e)); background-image: -webkit-linear-gradient(top,#fceda7,#fadb4e); background-image: -moz-linear-gradient(top,#fceda7,#fadb4e); background-image: -ms-linear-gradient(top,#fceda7,#fadb4e); background-image: -o-linear-gradient(top,#fceda7,#fadb4e); background-image: linear-gradient(top,#fceda7,#fadb4e) }
+
+.ui-btn-up-e a.ui-link-inherit { color: #333 }
+
+.ui-btn-hover-e { border: 1px solid #e79952; background: #fbe26f; font-weight: bold; color: #111; text-shadow: 0 1px 1px #fff; background-image: -webkit-gradient(linear,left top,left bottom,from(#fcf0b5),to(#fbe26f)); background-image: -webkit-linear-gradient(top,#fcf0b5,#fbe26f); background-image: -moz-linear-gradient(top,#fcf0b5,#fbe26f); background-image: -ms-linear-gradient(top,#fcf0b5,#fbe26f); background-image: -o-linear-gradient(top,#fcf0b5,#fbe26f); background-image: linear-gradient(top,#fcf0b5,#fbe26f) }
+
+.ui-btn-hover-e a.ui-link-inherit { color: #333 }
+
+.ui-btn-down-e { border: 1px solid #f7c942; background: #fceda7; font-weight: bold; color: #111; text-shadow: 0 1px 1px #fff; background-image: -webkit-gradient(linear,left top,left bottom,from(#fadb4e),to(#fceda7)); background-image: -webkit-linear-gradient(top,#fadb4e,#fceda7); background-image: -moz-linear-gradient(top,#fadb4e,#fceda7); background-image: -ms-linear-gradient(top,#fadb4e,#fceda7); background-image: -o-linear-gradient(top,#fadb4e,#fceda7); background-image: linear-gradient(top,#fadb4e,#fceda7) }
+
+.ui-btn-down-e a.ui-link-inherit { color: #333 }
+
+.ui-btn-up-e,.ui-btn-hover-e,.ui-btn-down-e { font-family: Helvetica,Arial,sans-serif; text-decoration: none }
+
+a.ui-link-inherit { text-decoration: none!important }
+
+.ui-btn-active { border-radius: 3px; border: 1px solid #444; background: #eee; font-weight: bold; color: #444; cursor: pointer; text-shadow: 0 -1px 1px #fff; text-decoration: none; background-image: -webkit-gradient(linear,left top,left bottom,from(#fff),to(#eee)); background-image: -webkit-linear-gradient(top,#fff,#eee); background-image: -moz-linear-gradient(top,#fff,#eee); background-image: -ms-linear-gradient(top,#fff,#eee); background-image: -o-linear-gradient(top,#fff,#eee); background-image: linear-gradient(top,#111,#000); outline: 0 }
+
+/*input.ui-input-text { background-color: #fff !important; color: #485664 !important; }*/
+
+input.ui-input-text.ui-body-null.ui-corner-all.ui-shadow-inset.ui-body-c { background-color: #fff !important; }
+
+textarea.ui-input-text.ui-body-null.ui-corner-all.ui-shadow-inset.ui-body-c { background-color: #fff; }
+
+input#category-title.ui-input-text.ui-body-null.ui-corner-all.ui-shadow-inset.ui-body-c { }
+
+label.ui-input-text, label.ui-select, label.ui-slider { color: #a5564f; font-weight: bold; font-size: 1em; }
+
+.list-item-editable p.ui-li-aside { width: 40px; }
+
+.list-item-editable p.ui-li-aside a.item-edit { right:5px; margin-top:-9px; position:absolute; width:25px; height:80px; text-indent: 99999px; }
+
+li.ajax-loading-img { text-align:center; }
+
+/* Seems to fix the extra few pixels you can scroll to the right */
+.ui-header { width: auto; }
View
BIN www/assets/css/images/ajax-loader.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN www/assets/css/images/icons-18-black.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN www/assets/css/images/icons-18-white.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN www/assets/css/images/icons-36-black.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN www/assets/css/images/icons-36-white.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
1,892 www/assets/css/jquery.mobile-1.0rc2.css
1,892 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
BIN www/assets/images/ajax-loader.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN www/assets/images/logo.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
985 www/assets/js/defaults.js
@@ -0,0 +1,985 @@
+var japp = {
+ init: function() {
+ this.requires_api_version = 0.1;
+ this.ajax_loader = 'assets/images/ajax-loader.gif';
+ this.is_loading = {};
+ this.available = false;
+ this.cache = true;
+
+ this.cache_types = {
+ 'category': {
+ 0: 'joomla.category.{0}.id.{1}',
+ 1: 'joomla.parentcategories.{0}.id.{1}',
+ 2: 'joomla.categories.*'
+ }
+ };
+ this.load_tries = new Array();
+ },
+
+ /* Core Joomla */
+ get_joomla_accesslevels: function( fresh ) {
+ var context = 'joomla.accesslevel';
+ if ( japp.cache && !fresh && jcache.get( context ) ) {
+ return jcache.get( context );
+ }
+
+ this._ajax(
+ {
+ app: 'core',
+ resource: 'accesslevel'
+ },
+ function( data ) {
+ // Try again?
+ if ( japp._object_empty( data ) ) {
+ japp._try_server_request_again( 'joomla_accesslevel', '',
+ function(){ japp.get_joomla_accesslevels( fresh ); });
+ } else {
+ jcache.set( context, data );
+ }
+ }, { async: false });
+
+ return jcache.get( context );
+ },
+
+ get_joomla_categories_list: function( extension, fresh ) {
+ var context = 'joomla.categorieslist.' + extension;
+ if ( japp.cache && !fresh && jcache.get( context ) ) {
+ return jcache.get( context );
+ }
+
+ this._ajax(
+ {
+ app: 'core',
+ resource: 'categories',
+ extension: extension
+ },
+ function( data ) {
+ // Try again?
+ if ( japp._object_empty( data ) ) {
+ japp._try_server_request_again( 'joomla_categories', extension,
+ function(){ japp.get_joomla_categories_list( extension, fresh ); });
+ } else {
+ jcache.set( context, data );
+ }
+ }, { async: false });
+
+ return jcache.get( context );
+ },
+
+ get_joomla_parentcategories: function( id, extension, fresh ) {
+ var context = 'joomla.parentcategories.' + extension + '.id.' + id;
+ if ( japp.cache && !fresh && jcache.get( context ) ) {
+ return jcache.get( context );
+ }
+
+ this._ajax(
+ {
+ app: 'core',
+ resource: 'categoryparent',
+ id: id,
+ extension: extension
+ },
+ function( data ) {
+ // Try again?
+ if ( japp._object_empty( data ) ) {
+ japp._try_server_request_again( 'get_joomla_parentcategories', id,
+ function(){ japp.get_joomla_parentcategories( id, extension, fresh ) } );
+ } else {
+ jcache.set( context, data );
+ }
+ }, { async: false });
+
+ return jcache.get( context );
+ },
+
+ get_content_language: function( fresh ) {
+ var context = 'joomla.contentlanguage';
+ if ( japp.cache && !fresh && jcache.get( context ) ) {
+ return jcache.get( context );
+ }
+
+ this._ajax(
+ {
+ app: 'core',
+ resource: 'contentlanguage'
+ },
+ function( data ) {
+ // Try again?
+ if ( japp._object_empty( data ) ) {
+ japp._try_server_request_again( 'content_language', '',
+ function(){ japp.get_content_language( fresh ); });
+ } else {
+ jcache.set( context, data );
+ }
+ }, { async: false });
+
+ return jcache.get( context );
+ },
+
+ get_component_layout: function( extension, view, client, template, fresh ) {
+ if ( typeof template == 'undefined' ) {
+ template = '';
+ }
+
+ var context = 'joomla.componentlayout.' + extension + '.view.' + view + '.client.'
+ + client + '.template.' + template;
+ if ( japp.cache && !fresh && jcache.get( context ) ) {
+ return jcache.get( context );
+ }
+
+ this._ajax(
+ {
+ app: 'core',
+ resource: 'componentlayout',
+ client_id: client,
+ extension: extension,
+ _view: view,
+ template: template
+ },
+ function( data ) {
+ // Try again?
+ if ( japp._object_empty( data ) ) {
+ japp._try_server_request_again( 'componentlayout' + client + extension,
+ view + template,
+ function(){
+ japp.get_component_layout( extension, view, client, template, fresh );
+ });
+ } else {
+ jcache.set( context, data );
+ }
+ }, { async: false });
+
+ return jcache.get( context );
+ },
+
+ get_template_style: function( client, template, fresh ) {
+ if ( typeof client == 'undefined' ) {
+ client = '';
+ }
+
+ if ( typeof template == 'undefined' ) {
+ template = '';
+ }
+
+ var context = 'joomla.templatestyle.client.' + client + '.template.' + template;
+ if ( japp.cache && !fresh && jcache.get( context ) ) {
+ return jcache.get( context );
+ }
+
+ this._ajax(
+ {
+ app: 'core',
+ resource: 'templatestyle',
+ client: client,
+ template: template
+ },
+ function( data ) {
+ // Try again?
+ if ( japp._object_empty( data ) ) {
+ japp._try_server_request_again( 'templatestyle' + client, template,
+ function(){
+ japp.get_template_style( client, template, fresh );
+ });
+ } else {
+ jcache.set( context, data );
+ }
+ }, { async: false });
+
+ return jcache.get( context );
+ },
+
+ get_joomla_users_list: function( columns, fresh ) {
+ if ( typeof columns == 'undefined' ) {
+ columns = '';
+ }
+
+ var context = 'joomla.userslist.' + columns;
+ if ( japp.cache && !fresh && jcache.get( context ) ) {
+ return jcache.get( context );
+ }
+
+ this._ajax(
+ {
+ app: 'users',
+ resource: 'userslist',
+ columns: columns
+ },
+ function( data ) {
+ // Try again?
+ if ( japp._object_empty( data ) ) {
+ japp._try_server_request_again( 'joomla_userslist', columns,
+ function(){ japp.get_joomla_users_list( columns, fresh ); });
+ } else {
+ jcache.set( context, data );
+ }
+ }, { async: false });
+
+ return jcache.get( context );
+ },
+
+ get_joomla_menus_list: function( fresh ) {
+ var context = 'joomla.menus.list';
+ if ( japp.cache && !fresh && jcache.get( context ) ) {
+ return jcache.get( context );
+ }
+
+ this._ajax(
+ {
+ app: 'core',
+ resource: 'jhtml',
+ type: 'menu.menus'
+ },
+ function( data ) {
+ // Try again?
+ if ( japp._object_empty( data ) ) {
+ japp._try_server_request_again( 'joomlamenuslist', '',
+ function(){
+ japp.get_joomla_menus_list( fresh );
+ });
+ } else {
+ jcache.set( context, data );
+ }
+ }, { async: false });
+
+ return jcache.get( context );
+ },
+
+ get_joomla_menuparent_list: function( menutype, id, fresh ) {
+ var context = 'joomla.menuparent.list';
+ if ( japp.cache && !fresh && jcache.get( context ) ) {
+ return jcache.get( context );
+ }
+
+ this._ajax(
+ {
+ app: 'core',
+ resource: 'menuparent',
+ menutype: menutype,
+ id: id
+ },
+ function( data ) {
+ // Try again?
+ if ( japp._object_empty( data ) ) {
+ japp._try_server_request_again( 'joomlamenuparent' + menutype, id,
+ function(){
+ japp.get_joomla_menuparent_list( menutype, id, fresh );
+ });
+ } else {
+ jcache.set( context, data );
+ }
+ }, { async: false });
+
+ return jcache.get( context );
+ },
+
+ /* Categories */
+ load_categories: function( element, extension, limitstart, limit, fresh ) {
+ if ( this._is_loading('categories') || !element || !extension ) {
+ return false;
+ }
+
+ var el = jQuery(element);
+ this._started_loading('categories');
+
+ if ( typeof limitstart == 'undefined' ) { limitstart = jQuery(el).attr('g:limitstart') || 0; }
+ if ( typeof limit == 'undefined' ) { limit = 20; }
+
+ var func = function( data ) {
+ jQuery('#ajax-loading-img').remove();
+ jcache.set( context, data, {expiry: date_times.seconds( date_times.hour/2 )} );
+
+ // We reached the end of articles
+ if ( !data.length ) {
+ japp.unbind_scroll_listener();
+ japp._stopped_loading('categories', true);
+ return;
+ }
+
+ el = jQuery(el);
+
+ jQuery(data).each(function(){
+ level = '';
+ if ( Number(this.level) > 1 ) {
+ for (var i=1; i < this.level; i++) {
+ level += '<span class="gi">|&mdash;</span>';
+ };
+ }
+ state = japp.get_item_state( this.published );
+ jQuery(el).append('<li><a href="category.html?id=' + this.id + '">'
+ + '<h3>' + level + this.title + '</h3>'
+ + '<p><span class="item-author">' + this.author_name
+ + '</span> / <span class="item-' + state.toLowerCase() + '">'
+ + state + '</span> / <span class="item-'
+ + this.access_level.toLowerCase() + '">'
+ + this.access_level + '</span></p>'
+ + '</a></li>');
+ });
+
+ jQuery(el).listview('refresh').attr('g:limitstart',
+ parseInt( limitstart ) + parseInt( limit ) );
+
+ // Add loading animation
+ jQuery(el).append('<li id="ajax-loading-img"><img src="'
+ + japp.ajax_loader + '" /></li>');
+
+ // Add scroll listener
+ if ( 0 == limitstart ) {
+ japp.scroll_bottom_listener( '#ajax-loading-img',
+ function(){ japp.load_categories( element, extension ); } );
+ }
+
+ japp._stopped_loading('categories', true);
+ };
+
+ var context = 'joomla.categories.' + extension + '.' + limitstart + '.' + limit;
+ if ( japp.cache && !fresh && jcache.get( context ) ) {
+ func( jcache.get( context ) );
+ } else {
+ this._ajax(
+ {
+ app: 'categories',
+ resource: 'categories',
+ extension: extension,
+ limitstart: limitstart,
+ limit: limit
+ }, func );
+ }
+ },
+
+ load_category: function( id, extension ) {
+ category = this.get_category( id, extension );
+
+ // Populate all category fields
+ jQuery('#category-title').val(category.title);
+ jQuery('#category-alias').val(category.alias);
+ jQuery('#category-parent-id').val(category.parent_id).selectmenu();
+ jQuery('#category-published').val(category.published).selectmenu('refresh');
+ jQuery('#category-featured').val(category.featured).slider('refresh');
+ jQuery('#category-access').val(category.access).selectmenu();
+ jQuery('#category-language').val(category.langugae).selectmenu();
+ jQuery('#category-description').val( category.description );
+ jQuery('#category-created-user-id').val(category.created_by).selectmenu();
+ jQuery('#category-category-layout').val(category.params.category_layout).selectmenu();
+ jQuery('#category-note').val(category.note);
+ jQuery('#category-meta-description').val(category.metadesc);
+ jQuery('#category-meta-keywords').val(category.metakey);
+ jQuery('#category-metadata-robots').val(category.metadata.robots);
+ jQuery('#category-metadata-author').val(category.metadata.author);
+ jQuery('#category-extension').val(category.extension);
+ jQuery('#category-id').val(category.id);
+
+ this._stop_loader();
+ },
+
+ get_category: function( id, extension, fresh ) {
+ var context = 'joomla.category.' + extension + '.id.' + id;
+ if ( japp.cache && !fresh && jcache.get( context ) ) {
+ return jcache.get( context );
+ }
+
+ this._ajax(
+ {
+ app: 'categories',
+ resource: 'category',
+ id: id,
+ extension: extension
+ },
+ function( data ) {
+ // Try again?
+ if ( japp._object_empty( data ) ) {
+ japp._try_server_request_again( 'content_category', id,
+ function(){ japp.get_category( id, extension, fresh ); });
+ } else {
+ jcache.set( context, data );
+ }
+ }, { async: false });
+
+ return jcache.get( context );
+ },
+
+ save_category: function( postdata ) {
+ if ( typeof postdata == 'undefined' ) {
+ _data = jQuery('#category-form').serialize();
+ postdata = jQuery.deparam( _data );
+ }
+
+ // Add defaults
+ postdata.app = 'categories';
+ postdata.resource = 'category';
+ postdata.jform['extension'] = 'com_content';
+
+ this._ajax(
+ postdata,
+ function( data ) {
+ japp._stop_loader();
+ if ( data.success ) {
+ _alert( data.message, null, 'Success' );
+ jQuery('#category-id').val(data.id);
+ jQuery('#category-delete').css('display', 'block');
+
+ japp.clear_cache( 'category', postdata.jform['extension'], data.id );
+ } else {
+ _alert( data.message, null, 'Error' );
+ }
+ }, { async: false, type: ( ( postdata.jform.id ) ? 'PUT' : 'POST' ) });
+ },
+
+ delete_category: function() {
+ id = jQuery('#category-id').val();
+
+ if ( !id ) {
+ japp._stop_loader();
+ _alert( 'Category not found' );
+ return false;
+ }
+
+ var answer = confirm( 'Are you sure you want to delete this category?' );
+ if ( !answer ) {
+ japp._stop_loader();
+ return false;
+ }
+
+ this._ajax(
+ {
+ app: 'categories',
+ resource: 'categories',
+ task: 'delete',
+ cid: { 0: id }
+ },
+ function( data ) {
+ japp._stop_loader();
+ if ( data.success ) {
+ jQuery('#categories-list ul').html('');
+ limit = jQuery('#categories-list ul').attr('g:limitstart') || 20;
+
+ if ( data.message ) {
+ _alert( data.message, null, 'Success' );
+ }
+
+ japp.clear_cache( 'category', 'com_content', id );
+ jQuery('#page-category .ui-header a:first').trigger('click');
+ } else {
+ _alert( data.message, null, 'Error' );
+ }
+ }, { async: false, type: 'DELETE' });
+ },
+
+ /* Other */
+ get_api_user: function( func, _data ) {
+ this._ajax(
+ {
+ app: 'api',
+ resource: 'user'
+ },
+ function( data ) {
+ if ( data.success ) {
+ // Lets run our success function
+ func( data, _data );
+ } else {
+ japp._stop_loader();
+ _alert( data.message, null, 'Error' );
+ }
+ }, { async: false });
+ },
+
+ /* Utilities */
+ get_item_state: function( state ) {
+ switch( Number( state ) ) {
+ case 1:
+ state = 'Published';
+ break;
+ case 0:
+ state = 'Unpublished';
+ break;
+ case 2:
+ state = 'Archived';
+ break;
+ default:
+ state = 'Trash';
+ break;
+ }
+
+ return state;
+ },
+
+ scroll_bottom_listener: function( element, func ) {
+ this.unbind_scroll_listener();
+ jQuery(window).bind('scroll.removable', function(){
+ if ( !japp.belowthefold(element) && !japp.rightoffold(element) ) {
+ if ( typeof func == 'function' ) {
+ func();
+ } else {
+ eval( func + '()' );
+ }
+ }
+ });
+
+ setTimeout(function(){
+ if ( !japp.belowthefold(element) && !japp.rightoffold(element) ) {
+ if ( typeof func == 'function' ) {
+ func();
+ } else {
+ eval( func + '()' );
+ }
+ }}, 100);
+ },
+
+ unbind_scroll_listener: function() {
+ jQuery(window).unbind('scroll.removable');
+ },
+
+ belowthefold: function( element ) {
+ var fold = jQuery(window).height() + jQuery(window).scrollTop();
+
+ return fold <= jQuery(element).offset().top + 20;
+ },
+
+ rightoffold: function( element, settings ) {
+ var fold = jQuery(window).width() + jQuery(window).scrollLeft();
+
+ return fold <= jQuery(element).offset().left - 0;
+ },
+
+ add_cache_type: function( type, caches ) {
+ obj = {};
+ obj[type] = caches;
+ this.cache_types = this._merge_objects( this.cache_types, obj );
+ },
+
+ clear_cache: function( type ) {
+ types = this.cache_types[type];
+
+ if ( !types ) {
+ return;
+ }
+
+ args = Array.prototype.slice.call( arguments, 1 );
+
+ for ( var key in types ) {
+ type = types[key];
+
+ // Check for wildcard
+ i = (type + '').indexOf('*', 0);
+ if ( i !== -1 ) {
+ // Find all caches that match
+ regex = new RegExp(
+ '^site\\.\\d\\.' + type.replace(/\./g, '\\\.').replace('*', '.*'), 'i' );
+ for ( var s in localStorage ) {
+ // In case the Android decides to be temperamental again.
+ // p = s.toString();
+
+ matches = s.match(regex);
+
+ if ( null == matches ) {
+ continue;
+ }
+
+ // The .meta key will also get catched anyways, so no need here
+ jcache.remove( matches[0], true );
+ }
+ } else {
+ key = String.prototype.format.apply( type, args );
+ jcache.remove( key );
+ jcache.remove( key + '.meta' );
+ }
+ }
+
+ return true;
+ },
+
+ _load_asset: function( filename, filetype, async ) {
+ if ( 'js' == filetype ) {
+ var sc = document.createElement('script');
+ sc.setAttribute( 'type', 'text/javascript' );
+ sc.setAttribute( 'src', filename );
+ } else if ( 'css' == filetype ) {
+ var sc=document.createElement( 'link' );
+ sc.setAttribute( 'rel', 'stylesheet' );
+ sc.setAttribute( 'type', 'text/css' );
+ sc.setAttribute( 'href', filename );
+ }
+
+ if ( async ) {
+ sc.async = true;
+ } else {
+ sc.async = false;
+ }
+
+ if ( typeof sc != 'undefined' )
+ document.getElementsByTagName('head')[0].appendChild( sc );
+ },
+
+ _start_loader: function( msg, callback ) {
+ if ( this.is_loading.loader ) {
+ return false;
+ }
+
+ if ( typeof msg != 'undefined' ) {
+ jQuery.mobile.loadingMessage = msg;
+ }
+
+ this.is_loading.loader = true;
+ jQuery.mobile.showPageLoadingMsg();
+ // Just in case
+ this.loadMsgDelay = setTimeout("japp._stop_loader();", 30000);
+
+ if ( typeof callback == 'function' ) {
+ setTimeout(function(){callback();}, 250);
+ }
+ },
+
+ _stop_loader: function() {
+ if ( this.is_loading.loader ) {
+ clearTimeout( this.loadMsgDelay );
+ this.is_loading.loader = false;
+ jQuery.mobile.hidePageLoadingMsg();
+
+ // Reset message
+ jQuery.mobile.loadingMessage = 'Loading';
+ }
+ },
+
+ _started_loading: function(type) {
+ this.is_loading[type] = true;
+ },
+
+ _is_loading: function(type) {
+ if ( this.is_loading[type] ) {
+ return true;
+ }
+
+ return false;
+ },
+
+ _stopped_loading: function(type, stop_loader) {
+ this.is_loading[type] = false;
+ if ( stop_loader ) {
+ this._stop_loader();
+ }
+ },
+
+ _ajax: function( data, success, opts ) {
+ options = {
+ url: this.site_url,
+ async: true,
+ type: 'GET',
+ dataType: 'json',
+ error: function(jxhr){
+ japp._stop_loader();
+ if ( typeof jxhr.responseText == 'undefined' || !jxhr.responseText ) {
+ if ( japp._check_device_connection() ) {
+ // Show error if device connected to internet but no connection to server
+ _alert( 'An error ocurred: There was no response from the server. 444.', null, 'Error' );
+ }
+ return;
+ }
+
+ try {
+ t = jQuery.parseJSON( jxhr.responseText );
+ if ( t.message ) {
+ _alert( t.message, null, 'Error' );
+ } else {
+ _alert( 'An error ocurred: There was no response from the server.', null, 'Error' );
+ }
+ } catch(e) {
+ _alert( 'An error ocurred: There was no response from the server. 409.', null, 'Error' );
+ }
+ }
+ };
+
+ if ( typeof opts != 'undefined' ) {
+ options = this._merge_objects( options, opts );
+ }
+
+ // Add default data parameters
+ if ( typeof data.option == 'undefined' ) {
+ data.option = 'com_api';
+ }
+ if ( typeof data.key == 'undefined' ) {
+ data.key = this.api_key;
+ }
+
+ return jQuery.ajax({
+ url: options.url,
+ dataType: options.dataType,
+ cache: false,
+ async: options.async,
+ type: options.type,
+ data: data,
+ success: success,
+ error: options.error
+ }).responseText;
+ },
+
+ _try_server_request_again: function( filter1, filter2, func ) {
+ if ( !filter2 ) {
+ if ( typeof japp.load_tries[filter1] == 'undefined' ) {
+ japp.load_tries[filter1] = 1;
+ } else {
+ japp.load_tries[filter1]++;
+ }
+
+ if ( japp.load_tries[filter1] >= 3 ) {
+ alert( 'There is an error connecting to the server, please try again.' );
+ japp.load_tries[filter1] = 0;
+
+ return false;
+ }
+ } else {
+ if ( typeof japp.load_tries[filter1][filter2] == 'undefined' ) {
+ japp.load_tries[filter1][filter2] = 1;
+ } else {
+ japp.load_tries[filter1][filter2]++;
+ }
+
+ if ( japp.load_tries[filter1][filter2] >= 3 ) {
+ alert( 'There is an error connecting to the server, please try again.' );
+ japp.load_tries[filter1][filter2] = 0;
+
+ return false;
+ }
+ }
+
+ try {
+ if ( typeof func == 'string' ) {
+ japp.func();
+ } else {
+ func();
+ }
+ } catch(e) {}
+
+ return true;
+ },
+
+ _object_empty: function( ob ) {
+ for ( var i in ob ) {
+ return false;
+ }
+
+ return true;
+ },
+
+ _merge_objects: function( obj1, obj2 ) {
+ var obj3 = {};
+
+ for ( var attrname in obj1 ) { obj3[attrname] = obj1[attrname]; }
+ for ( var attrname in obj2 ) { obj3[attrname] = obj2[attrname]; }
+
+ return obj3;
+ },
+
+ _trigger_dialog: function(dialogtype) {
+ japp.dialogtype = dialogtype;
+
+ jQuery('.customdialog-link').trigger('click');
+
+ return false;
+ },
+
+ _db_success: function(){},
+ _db_error: function(){}
+};
+
+japp.init();
+
+jQuery(document).ready(function(){
+ japp.get_api_user(function(data, _data){japp.api_user = data.user;});
+});
+
+function _populate_select( selector, obj, _key, _value, opts ) {
+ options = {
+ show_default: false,
+ default_value: 0,
+ default_text: '-- Select --',
+ select_option: false,
+ selected_value: 0,
+ refresh: false,
+ rebuild: false
+ };
+
+ if ( typeof opts != 'undefined' ) {
+ options = japp._merge_objects( options, opts );
+ }
+
+ el = jQuery(selector);
+ el.html('');
+ html = '';
+
+ if ( options.show_default ) {
+ html += '<option value="' + options.default_value + '">'
+ + options.default_text + '</option>';
+ }
+
+ jQuery.each(obj, function( key, row ){
+ html += '<option value="' + eval( _key ) + '">' + eval( _value ) + '</option>';
+ });
+
+ el.html(html);
+
+ if ( options.refresh ) {
+ el.selectmenu('refresh');
+ }
+
+ if ( options.select_option ) {
+ el.val(options.selected_value);
+ el[0].value = options.selected_value;
+ }
+
+ if ( options.refresh ) {
+ if ( options.rebuild ) {
+ el.selectmenu('refresh', true);
+ } else {
+ el.selectmenu('refresh');
+ }
+ }
+}
+
+function _populate_group_select( selector, obj, _key, _value, opts ) {
+ options = {
+ opt_grp_items: 'items',
+ select_option: false,
+ selected_value: 0,
+ refresh: false,
+ rebuild: false,
+ singlekey: '',
+ singlevalue: ''
+ };
+
+ if ( typeof opts != 'undefined' ) {
+ options = japp._merge_objects( options, opts );
+ }
+
+ el = jQuery(selector);
+ el.html('');
+ html = '';
+ counter = 0;
+
+ jQuery.each(obj, function( opt_grp_key, opt_grp ) {
+ // Check to see if this value is a single option and not in an optgroup
+ singlevalue = eval( options.singlevalue );
+ singletext = eval( options.singletext );
+ if ( typeof singlevalue != 'undefined' && singletext ) {
+ html += '<option value="' + singlevalue + '">' + singletext + '</option>';
+ return;
+ }
+
+ // Get label
+ opt_grp_label = opt_grp['text'] || opt_grp_key;
+
+ // Create option group warpper
+ html += '<optgroup label="' + opt_grp_label + '">';
+ jQuery.each( (options.opt_grp_items)
+ ? eval( 'opt_grp[\'' + options.opt_grp_items + '\']' )
+ : opt_grp,
+ function( key, row ) {
+ html += '<option value="' + eval( _key ) + '">' + eval( _value ) + '</option>';
+ });
+ html += '</optgroup>';
+ });
+
+ el.html(html);
+
+ if ( options.refresh ) {
+ el.selectmenu('refresh');
+ }
+
+ if ( options.select_option ) {
+ el.val(options.selected_value);
+ el[0].value = options.selected_value;
+ }
+
+ if ( options.refresh ) {
+ if ( options.rebuild ) {
+ el.selectmenu('refresh', true);
+ } else {
+ el.selectmenu('refresh');
+ }
+ }
+}
+
+var date_times = {
+ minute: 60,
+ hour: 3600,
+ day: 86400,
+ week: 604800,
+
+ seconds: function( seconds ) {
+ var now = new Date();
+ var future = new Date();
+ future.setSeconds( seconds );
+
+ return future;
+ }
+};
+
+function _fix_textarea_height( el ) {
+ extraLineHeight = 15;
+ scrollHeight = el[0].scrollHeight;
+ clientHeight = el[0].clientHeight;
+ if ( clientHeight < scrollHeight ) {
+ el.css({
+ height: (scrollHeight + extraLineHeight)
+ });
+ }
+}
+
+function _alert( msg, func, title, btn ) {
+ alert(msg);
+
+ if ( typeof func == 'function' ) {
+ func();
+ };
+
+ // Read more for device notification:
+ // http://docs.phonegap.com/en/1.1.0/phonegap_notification_notification.md.html#notification.alert
+}
+
+function _confirm( msg, func, title, btn ) {
+ var answer = confirm( msg );
+
+ // This is not the correct implementation of what happens on the phone,
+ // please read the link below for more information.
+ if ( typeof func == 'function' ) {
+ func( answer );
+ };
+
+ // Read more for device notification:
+ // http://docs.phonegap.com/en/1.1.0/phonegap_notification_notification.md.html#notification.confirm
+}
+
+function _gup( name, loc ) {
+ _name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
+ var regexS = "[\\?&]" + _name + "=([^&#]*)";
+ var regex = new RegExp( regexS );
+
+ var hash_test = false;
+ if ( window.location.hash && !loc ) {
+ loc = window.location.hash
+ hash_test = true;
+ }
+
+ if ( !loc ) {
+ loc = window.location.href;
+ }
+
+ var results = regex.exec( loc );
+
+ if ( results == null ) {
+ if ( hash_test ) {
+ return _gup( name, window.location.href );
+ }
+ return '';
+ } else {
+ return results[1];
+ }
+}
+
+String.prototype.format = function() {
+ var args = arguments;
+ return this.replace(/{(\d+)}/g, function(match, number) {
+ return typeof args[number] != 'undefined'
+ ? args[number]
+ : match
+ ;
+ });
+};
View
177 www/assets/js/jcache.js
@@ -0,0 +1,177 @@
+/**
+ * Proxy for localStorage
+ */
+var jcache = {
+ // Public method to get value by key
+ get: function( key ) {
+ if ( !this.has( key, true ) ) {
+ return null;
+ }
+
+ // Retrieve value
+ var value = window.localStorage.getItem( key );
+ var meta = this._get_meta( key );
+
+ var now = new Date();
+ if ( meta.expiry && Date.parse( meta.expiry ) <= now ) {
+ // Key has expired, remove
+ this.remove( key, true );
+ this.remove( key + '.meta', true );
+ return null;
+ } else if ( !value ) {
+ // In case there was no value found
+ return null;
+ } else {
+ if ( meta.isjson ) {
+ return eval( '(' + value + ')' );
+ } else {
+ return value;
+ }
+ }
+ },
+
+ // Public method to store key/value
+ set: function( key, value, opts ) {
+ meta = {
+ expiry: false,
+ isjson: true,
+ overwrite: false
+ };
+
+ if ( typeof opts != 'undefined' ) {
+ meta = this._merge_objects( meta, opts );
+ } else {
+ // Check if our value is an object
+ if ( typeof value != 'object' ) {
+ meta.isjson = false;
+ }
+ }
+
+ if ( !meta.overwrite && jcache.get( key, true ) ) {
+ return;
+ }
+
+ if ( meta.isjson ) {
+ // Always serialize as JSON
+ value = JSON.stringify( value );
+ }
+
+ window.localStorage.setItem( key, value );
+
+ // Set meta
+ meta.expiry = this._make_valid_expiry( meta.expiry );
+ this._set_meta( key, meta );
+ },
+
+ // Check if given key exists
+ has: function( key ) {
+ var value = window.localStorage.getItem( key );
+
+ return ( value != null && value != undefined );
+ },
+
+ // Copies the value of the first key to the second key.
+ copy: function( source, target ) {
+ // Copy value
+ var value = this.get( source );
+ this.set( target, value );
+
+ // Copy meta
+ var meta = this.get( source + '.meta' );
+ this.set( target + '.meta', meta );
+ },
+
+ // Renames the first key to the second key.
+ rename: function( source, target ) {
+ var value = this.get( source );
+ this.set( target, value );
+ var meta = this.get( source + '.meta' );
+ this.set( target + '.meta', meta );
+
+ this.remove( source );
+ this.remove( source + '.meta' );
+ },
+
+ // Removes the given key
+ remove: function( key ) {
+ window.localStorage.removeItem( key );
+ },
+
+ // Public method to wipe LS
+ clear: function() {
+ window.localStorage.clear();
+ },
+
+ /* Private methods */
+
+ _get_meta: function( key ) {
+ meta = window.localStorage.getItem( key + '.meta' );
+ if ( !meta ) {
+ meta = '{}';
+ }
+
+ return eval( '(' + meta + ')' );
+ },
+
+ _set_meta: function( key, value ) {
+ value = JSON.stringify( value );
+ window.localStorage.setItem( key + '.meta', value );
+ },
+
+ /**
+ * Gets the expiry date for given key
+ * @param key string. The key to get
+ * @return mixed, value for key or NULL if no such key
+ */
+ _get_expiry: function( key ) {
+ var meta = this._get_meta( key );
+ if ( meta.expiry != false && meta.expiry != null ) {
+ meta = new Date( meta.expiry );
+ } else {
+ meta = false;
+ }
+
+ return meta;
+ },
+
+ /**
+ * Sets the expiry date for given key
+ * @param key string. The key to set
+ * @param expiry; RFC1123 date or false for no expiry
+ * @return mixed, value for key or NULL if no such key
+ */
+ _set_expiry: function( key, expiry ) {
+ if ( this.has( key, true ) ) {
+ date = this._make_valid_expiry( expiry );
+ meta = this._get_meta( key );
+ meta.expiry = date;
+ this._set_meta( key, meta );
+ return this._get_expiry( key );
+ } else {
+ return null;
+ }
+ },
+
+ _make_valid_expiry: function( expiry ) {
+ if ( !expiry ) {
+ // no expiry given; change from "undefined" to false - this value does not expire.
+ // expiry = false;
+ // Default to tomorrow
+ expiry = date_times.seconds( date_times.day );
+ } else {
+ // force to date type
+ expiry = new Date( expiry );
+ }
+
+ return expiry;
+ },
+
+ _merge_objects: function( obj1, obj2 ) {
+ var obj3 = {};
+
+ for ( var attrname in obj1 ) { obj3[attrname] = obj1[attrname]; }
+ for ( var attrname in obj2 ) { obj3[attrname] = obj2[attrname]; }
+
+ return obj3;
+ }
+};
View
9,046 www/assets/js/jquery-1.6.4.js
9,046 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
18 www/assets/js/jquery.ba-bbq.min.js
@@ -0,0 +1,18 @@
+/*
+ * jQuery BBQ: Back Button & Query Library - v1.2.1 - 2/17/2010
+ * http://benalman.com/projects/jquery-bbq-plugin/
+ *
+ * Copyright (c) 2010 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+ */
+(function($,p){var i,m=Array.prototype.slice,r=decodeURIComponent,a=$.param,c,l,v,b=$.bbq=$.bbq||{},q,u,j,e=$.event.special,d="hashchange",A="querystring",D="fragment",y="elemUrlAttr",g="location",k="href",t="src",x=/^.*\?|#.*$/g,w=/^.*\#/,h,C={};function E(F){return typeof F==="string"}function B(G){var F=m.call(arguments,1);return function(){return G.apply(this,F.concat(m.call(arguments)))}}function n(F){return F.replace(/^[^#]*#?(.*)$/,"$1")}function o(F){return F.replace(/(?:^[^?#]*\?([^#]*).*$)?.*/,"$1")}function f(H,M,F,I,G){var O,L,K,N,J;if(I!==i){K=F.match(H?/^([^#]*)\#?(.*)$/:/^([^#?]*)\??([^#]*)(#?.*)/);J=K[3]||"";if(G===2&&E(I)){L=I.replace(H?w:x,"")}else{N=l(K[2]);I=E(I)?l[H?D:A](I):I;L=G===2?I:G===1?$.extend({},I,N):$.extend({},N,I);L=a(L);if(H){L=L.replace(h,r)}}O=K[1]+(H?"#":L||!K[1]?"?":"")+L+J}else{O=M(F!==i?F:p[g][k])}return O}a[A]=B(f,0,o);a[D]=c=B(f,1,n);c.noEscape=function(G){G=G||"";var F=$.map(G.split(""),encodeURIComponent);h=new RegExp(F.join("|"),"g")};c.noEscape(",/");$.deparam=l=function(I,F){var H={},G={"true":!0,"false":!1,"null":null};$.each(I.replace(/\+/g," ").split("&"),function(L,Q){var K=Q.split("="),P=r(K[0]),J,O=H,M=0,R=P.split("]["),N=R.length-1;if(/\[/.test(R[0])&&/\]$/.test(R[N])){R[N]=R[N].replace(/\]$/,"");R=R.shift().split("[").concat(R);N=R.length-1}else{N=0}if(K.length===2){J=r(K[1]);if(F){J=J&&!isNaN(J)?+J:J==="undefined"?i:G[J]!==i?G[J]:J}if(N){for(;M<=N;M++){P=R[M]===""?O.length:R[M];O=O[P]=M<N?O[P]||(R[M+1]&&isNaN(R[M+1])?{}:[]):J}}else{if($.isArray(H[P])){H[P].push(J)}else{if(H[P]!==i){H[P]=[H[P],J]}else{H[P]=J}}}}else{if(P){H[P]=F?i:""}}});return H};function z(H,F,G){if(F===i||typeof F==="boolean"){G=F;F=a[H?D:A]()}else{F=E(F)?F.replace(H?w:x,""):F}return l(F,G)}l[A]=B(z,0);l[D]=v=B(z,1);$[y]||($[y]=function(F){return $.extend(C,F)})({a:k,base:k,iframe:t,img:t,input:t,form:"action",link:k,script:t});j=$[y];function s(I,G,H,F){if(!E(H)&&typeof H!=="object"){F=H;H=G;G=i}return this.each(function(){var L=$(this),J=G||j()[(this.nodeName||"").toLowerCase()]||"",K=J&&L.attr(J)||"";L.attr(J,a[I](K,H,F))})}$.fn[A]=B(s,A);$.fn[D]=B(s,D);b.pushState=q=function(I,F){if(E(I)&&/^#/.test(I)&&F===i){F=2}var H=I!==i,G=c(p[g][k],H?I:{},H?F:2);p[g][k]=G+(/#/.test(G)?"":"#")};b.getState=u=function(F,G){return F===i||typeof F==="boolean"?v(F):v(G)[F]};b.removeState=function(F){var G={};if(F!==i){G=u();$.each($.isArray(F)?F:arguments,function(I,H){delete G[H]})}q(G,2)};e[d]=$.extend(e[d],{add:function(F){var H;function G(J){var I=J[D]=c();J.getState=function(K,L){return K===i||typeof K==="boolean"?l(I,K):l(I,L)[K]};H.apply(this,arguments)}if($.isFunction(F)){H=F;return G}else{H=F.handler;F.handler=G}}})})(jQuery,this);
+/*
+ * jQuery hashchange event - v1.2 - 2/11/2010
+ * http://benalman.com/projects/jquery-hashchange-plugin/
+ *
+ * Copyright (c) 2010 "Cowboy" Ben Alman
+ * Dual licensed under the MIT and GPL licenses.
+ * http://benalman.com/about/license/
+ */
+(function($,i,b){var j,k=$.event.special,c="location",d="hashchange",l="href",f=$.browser,g=document.documentMode,h=f.msie&&(g===b||g<8),e="on"+d in i&&!h;function a(m){m=m||i[c][l];return m.replace(/^[^#]*#?(.*)$/,"$1")}$[d+"Delay"]=100;k[d]=$.extend(k[d],{setup:function(){if(e){return false}$(j.start)},teardown:function(){if(e){return false}$(j.stop)}});j=(function(){var m={},r,n,o,q;function p(){o=q=function(s){return s};if(h){n=$('<iframe src="javascript:0"/>').hide().insertAfter("body")[0].contentWindow;q=function(){return a(n.document[c][l])};o=function(u,s){if(u!==s){var t=n.document;t.open().close();t[c].hash="#"+u}};o(a())}}m.start=function(){if(r){return}var t=a();o||p();(function s(){var v=a(),u=q(t);if(v!==t){o(t=v,u);$(i).trigger(d)}else{if(u!==t){i[c][l]=i[c][l].replace(/#.*/,"")+"#"+u}}r=setTimeout(s,$[d+"Delay"])})()};m.stop=function(){if(!n){r&&clearTimeout(r);r=0}};return m})()})(jQuery,this);
View
6,814 www/assets/js/jquery.mobile-1.0rc2.js
6,814 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
480 www/assets/js/json2.js
@@ -0,0 +1,480 @@
+/*
+ http://www.JSON.org/json2.js
+ 2011-02-23
+
+ Public Domain.
+
+ NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+
+ See http://www.JSON.org/js.html
+
+
+ This code should be minified before deployment.
+ See http://javascript.crockford.com/jsmin.html
+
+ USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
+ NOT CONTROL.
+
+
+ This file creates a global JSON object containing two methods: stringify
+ and parse.
+
+ JSON.stringify(value, replacer, space)
+ value any JavaScript value, usually an object or array.
+
+ replacer an optional parameter that determines how object
+ values are stringified for objects. It can be a
+ function or an array of strings.
+
+ space an optional parameter that specifies the indentation
+ of nested structures. If it is omitted, the text will
+ be packed without extra whitespace. If it is a number,
+ it will specify the number of spaces to indent at each
+ level. If it is a string (such as '\t' or '&nbsp;'),
+ it contains the characters used to indent at each level.
+
+ This method produces a JSON text from a JavaScript value.
+
+ When an object value is found, if the object contains a toJSON
+ method, its toJSON method will be called and the result will be
+ stringified. A toJSON method does not serialize: it returns the
+ value represented by the name/value pair that should be serialized,
+ or undefined if nothing should be serialized. The toJSON method
+ will be passed the key associated with the value, and this will be
+ bound to the value
+
+ For example, this would serialize Dates as ISO strings.
+
+ Date.prototype.toJSON = function (key) {
+ function f(n) {
+ // Format integers to have at least two digits.
+ return n < 10 ? '0' + n : n;
+ }
+
+ return this.getUTCFullYear() + '-' +
+ f(this.getUTCMonth() + 1) + '-' +
+ f(this.getUTCDate()) + 'T' +
+ f(this.getUTCHours()) + ':' +
+ f(this.getUTCMinutes()) + ':' +
+ f(this.getUTCSeconds()) + 'Z';
+ };
+
+ You can provide an optional replacer method. It will be passed the
+ key and value of each member, with this bound to the containing
+ object. The value that is returned from your method will be
+ serialized. If your method returns undefined, then the member will
+ be excluded from the serialization.
+
+ If the replacer parameter is an array of strings, then it will be
+ used to select the members to be serialized. It filters the results
+ such that only members with keys listed in the replacer array are
+ stringified.
+
+ Values that do not have JSON representations, such as undefined or
+ functions, will not be serialized. Such values in objects will be
+ dropped; in arrays they will be replaced with null. You can use
+ a replacer function to replace those with JSON values.
+ JSON.stringify(undefined) returns undefined.
+
+ The optional space parameter produces a stringification of the
+ value that is filled with line breaks and indentation to make it
+ easier to read.
+
+ If the space parameter is a non-empty string, then that string will
+ be used for indentation. If the space parameter is a number, then
+ the indentation will be that many spaces.
+
+ Example:
+
+ text = JSON.stringify(['e', {pluribus: 'unum'}]);
+ // text is '["e",{"pluribus":"unum"}]'
+
+
+ text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
+ // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
+
+ text = JSON.stringify([new Date()], function (key, value) {
+ return this[key] instanceof Date ?
+ 'Date(' + this[key] + ')' : value;
+ });
+ // text is '["Date(---current time---)"]'
+
+
+ JSON.parse(text, reviver)
+ This method parses a JSON text to produce an object or array.
+ It can throw a SyntaxError exception.
+
+ The optional reviver parameter is a function that can filter and
+ transform the results. It receives each of the keys and values,
+ and its return value is used instead of the original value.
+ If it returns what it received, then the structure is not modified.
+ If it returns undefined then the member is deleted.
+
+ Example:
+
+ // Parse the text. Values that look like ISO date strings will
+ // be converted to Date objects.
+
+ myData = JSON.parse(text, function (key, value) {
+ var a;
+ if (typeof value === 'string') {
+ a =
+/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
+ if (a) {
+ return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
+ +a[5], +a[6]));
+ }
+ }
+ return value;
+ });
+
+ myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
+ var d;
+ if (typeof value === 'string' &&
+ value.slice(0, 5) === 'Date(' &&
+ value.slice(-1) === ')') {
+ d = new Date(value.slice(5, -1));
+ if (d) {
+ return d;
+ }
+ }
+ return value;
+ });
+
+
+ This is a reference implementation. You are free to copy, modify, or
+ redistribute.
+*/
+
+/*jslint evil: true, strict: false, regexp: false */
+
+/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
+ call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
+ getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
+ lastIndex, length, parse, prototype, push, replace, slice, stringify,
+ test, toJSON, toString, valueOf
+*/
+
+
+// Create a JSON object only if one does not already exist. We create the
+// methods in a closure to avoid creating global variables.
+
+var JSON;
+if (!JSON) {
+ JSON = {};
+}
+
+(function () {
+ "use strict";
+
+ function f(n) {
+ // Format integers to have at least two digits.
+ return n < 10 ? '0' + n : n;
+ }
+
+ if (typeof Date.prototype.toJSON !== 'function') {
+
+ Date.prototype.toJSON = function (key) {
+
+ return isFinite(this.valueOf()) ?
+ this.getUTCFullYear() + '-' +
+ f(this.getUTCMonth() + 1) + '-' +
+ f(this.getUTCDate()) + 'T' +
+ f(this.getUTCHours()) + ':' +
+ f(this.getUTCMinutes()) + ':' +
+ f(this.getUTCSeconds()) + 'Z' : null;
+ };
+
+ String.prototype.toJSON =
+ Number.prototype.toJSON =
+ Boolean.prototype.toJSON = function (key) {
+ return this.valueOf();
+ };
+ }
+
+ var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
+ gap,
+ indent,
+ meta = { // table of character substitutions
+ '\b': '\\b',
+ '\t': '\\t',
+ '\n': '\\n',
+ '\f': '\\f',
+ '\r': '\\r',
+ '"' : '\\"',
+ '\\': '\\\\'
+ },
+ rep;
+
+
+ function quote(string) {
+
+// If the string contains no control characters, no quote characters, and no
+// backslash characters, then we can safely slap some quotes around it.
+// Otherwise we must also replace the offending characters with safe escape
+// sequences.
+
+ escapable.lastIndex = 0;
+ return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
+ var c = meta[a];
+ return typeof c === 'string' ? c :
+ '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ }) + '"' : '"' + string + '"';
+ }
+
+
+ function str(key, holder) {
+
+// Produce a string from holder[key].
+
+ var i, // The loop counter.
+ k, // The member key.
+ v, // The member value.
+ length,
+ mind = gap,
+ partial,
+ value = holder[key];
+
+// If the value has a toJSON method, call it to obtain a replacement value.
+
+ if (value && typeof value === 'object' &&
+ typeof value.toJSON === 'function') {
+ value = value.toJSON(key);
+ }
+
+// If we were called with a replacer function, then call the replacer to
+// obtain a replacement value.
+
+ if (typeof rep === 'function') {
+ value = rep.call(holder, key, value);
+ }
+
+// What happens next depends on the value's type.
+
+ switch (typeof value) {
+ case 'string':
+ return quote(value);
+
+ case 'number':
+
+// JSON numbers must be finite. Encode non-finite numbers as null.
+
+ return isFinite(value) ? String(value) : 'null';
+
+ case 'boolean':
+ case 'null':
+
+// If the value is a boolean or null, convert it to a string. Note:
+// typeof null does not produce 'null'. The case is included here in
+// the remote chance that this gets fixed someday.
+
+ return String(value);
+
+// If the type is 'object', we might be dealing with an object or an array or
+// null.
+
+ case 'object':
+
+// Due to a specification blunder in ECMAScript, typeof null is 'object',
+// so watch out for that case.
+
+ if (!value) {
+ return 'null';
+ }
+
+// Make an array to hold the partial results of stringifying this object value.
+
+ gap += indent;
+ partial = [];
+
+// Is the value an array?
+
+ if (Object.prototype.toString.apply(value) === '[object Array]') {
+
+// The value is an array. Stringify every element. Use null as a placeholder
+// for non-JSON values.
+
+ length = value.length;
+ for (i = 0; i < length; i += 1) {
+ partial[i] = str(i, value) || 'null';
+ }
+
+// Join all of the elements together, separated with commas, and wrap them in
+// brackets.
+
+ v = partial.length === 0 ? '[]' : gap ?
+ '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' :
+ '[' + partial.join(',') + ']';
+ gap = mind;
+ return v;
+ }
+
+// If the replacer is an array, use it to select the members to be stringified.
+
+ if (rep && typeof rep === 'object') {
+ length = rep.length;
+ for (i = 0; i < length; i += 1) {
+ if (typeof rep[i] === 'string') {
+ k = rep[i];
+ v = str(k, value);
+ if (v) {
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
+ }
+ }
+ }
+ } else {
+
+// Otherwise, iterate through all of the keys in the object.
+
+ for (k in value) {
+ if (Object.prototype.hasOwnProperty.call(value, k)) {
+ v = str(k, value);
+ if (v) {
+ partial.push(quote(k) + (gap ? ': ' : ':') + v);
+ }
+ }
+ }
+ }
+
+// Join all of the member texts together, separated with commas,
+// and wrap them in braces.
+
+ v = partial.length === 0 ? '{}' : gap ?
+ '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' :
+ '{' + partial.join(',') + '}';
+ gap = mind;
+ return v;
+ }
+ }
+
+// If the JSON object does not yet have a stringify method, give it one.
+
+ if (typeof JSON.stringify !== 'function') {
+ JSON.stringify = function (value, replacer, space) {
+
+// The stringify method takes a value and an optional replacer, and an optional
+// space parameter, and returns a JSON text. The replacer can be a function
+// that can replace values, or an array of strings that will select the keys.
+// A default replacer method can be provided. Use of the space parameter can
+// produce text that is more easily readable.
+
+ var i;
+ gap = '';
+ indent = '';
+
+// If the space parameter is a number, make an indent string containing that
+// many spaces.
+
+ if (typeof space === 'number') {
+ for (i = 0; i < space; i += 1) {
+ indent += ' ';
+ }
+
+// If the space parameter is a string, it will be used as the indent string.
+
+ } else if (typeof space === 'string') {
+ indent = space;
+ }
+
+// If there is a replacer, it must be a function or an array.
+// Otherwise, throw an error.
+
+ rep = replacer;
+ if (replacer && typeof replacer !== 'function' &&
+ (typeof replacer !== 'object' ||
+ typeof replacer.length !== 'number')) {
+ throw new Error('JSON.stringify');
+ }
+
+// Make a fake root object containing our value under the key of ''.
+// Return the result of stringifying the value.
+
+ return str('', {'': value});
+ };
+ }
+
+
+// If the JSON object does not yet have a parse method, give it one.
+
+ if (typeof JSON.parse !== 'function') {
+ JSON.parse = function (text, reviver) {
+
+// The parse method takes a text and an optional reviver function, and returns
+// a JavaScript value if the text is a valid JSON text.
+
+ var j;
+
+ function walk(holder, key) {
+
+// The walk method is used to recursively walk the resulting structure so
+// that modifications can be made.
+
+ var k, v, value = holder[key];
+ if (value && typeof value === 'object') {
+ for (k in value) {
+ if (Object.prototype.hasOwnProperty.call(value, k)) {
+ v = walk(value, k);
+ if (v !== undefined) {
+ value[k] = v;
+ } else {
+ delete value[k];
+ }
+ }
+ }
+ }
+ return reviver.call(holder, key, value);
+ }
+
+
+// Parsing happens in four stages. In the first stage, we replace certain
+// Unicode characters with escape sequences. JavaScript handles many characters
+// incorrectly, either silently deleting them, or treating them as line endings.
+
+ text = String(text);
+ cx.lastIndex = 0;
+ if (cx.test(text)) {
+ text = text.replace(cx, function (a) {
+ return '\\u' +
+ ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
+ });
+ }
+
+// In the second stage, we run the text against regular expressions that look
+// for non-JSON patterns. We are especially concerned with '()' and 'new'
+// because they can cause invocation, and '=' because it can cause mutation.
+// But just to be safe, we want to reject all unexpected forms.
+
+// We split the second stage into 4 regexp operations in order to work around
+// crippling inefficiencies in IE's and Safari's regexp engines. First we
+// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
+// replace all simple value tokens with ']' characters. Third, we delete all
+// open brackets that follow a colon or comma or that begin the text. Finally,
+// we look to see that the remaining characters are only whitespace or ']' or
+// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
+
+ if (/^[\],:{}\s]*$/
+ .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
+ .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
+ .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
+
+// In the third stage we use the eval function to compile the text into a
+// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
+// in JavaScript: it can begin a block or an object literal. We wrap the text
+// in parens to eliminate the ambiguity.
+
+ j = eval('(' + text + ')');
+
+// In the optional fourth stage, we recursively walk the new structure, passing
+// each name/value pair to a reviver function for possible transformation.
+
+ return typeof reviver === 'function' ?
+ walk({'': j}, '') : j;
+ }
+
+// If the text is not JSON parseable, then a SyntaxError is thrown.
+
+ throw new SyntaxError('JSON.parse');
+ };
+ }
+}());
View
105 www/assets/js/main.js
@@ -0,0 +1,105 @@
+/* Categories */
+jQuery('#page-categories').live('pageshow',function(event){
+ try {
+ el = jQuery('#categories-list ul');
+ if ( !el.html() ) {
+ japp._start_loader();
+ japp.load_categories('#categories-list ul', 'com_content');
+ }
+ } catch(e){japp._stop_loader();}
+});
+jQuery('#page-category').live('pageshow',function(event){
+ try {
+ func = function() {
+ id = _gup( 'id' );
+
+ parentcat = japp.get_joomla_parentcategories( id, 'com_content' );
+ access = japp.get_joomla_accesslevels();
+ languages = japp.get_content_language();
+ users = japp.get_joomla_users_list();
+ layouts = japp.get_component_layout( 'com_content', 'category', 0 );
+
+ _populate_select( '#category-parent-id', parentcat, 'row.value', 'row.text' );
+ _populate_select( '#category-access', access, 'row.value', 'row.text' );
+ _populate_select( '#category-language', languages, 'row.value', 'row.text' );
+ _populate_select( '#category-created-user-id', users, 'key', 'row.name',
+ { select_option: true, selected_value: japp.api_user.id });
+ _populate_group_select( '#category-category-layout', layouts, 'row[\'value\']',
+ 'row[\'text\']' );
+
+ // New article
+ if ( !id ) {
+ japp._stop_loader();
+ jQuery('#category-parent-id,#category-access,#category-language,'
+ + '#category-created-user-id,#category-category-layout')
+ .selectmenu();
+
+ return;
+ }
+
+ japp.load_category( id, 'com_content' );
+
+ // Set page title
+ jQuery('#page-title').html( 'Edit category' );
+
+ jQuery('#category-delete').css('display', 'block');
+ }
+
+ japp._start_loader();
+ setTimeout('func();', 250);
+ } catch(e){japp._stop_loader();}
+});
+
+/* Utils */
+jQuery('#page-customdialog').live('pageshow',function(event){
+ try {
+ type = japp.dialogtype;
+
+ types = {
+ comingsoon: {
+ title: 'In the works!',
+ content: 'This feature will be available in future versions!<br />Please stay tuned.'
+ },
+ addnewsite: {
+ title: 'No can do!',
+ content: 'For this free version, we only allow 1 site. Sorry.'
+ },
+ newbie: {
+ title: 'Hi!',
+ content: 'Thank you for installing!<br /><br />Did you like the legs?<br />We are pretty hip like that.<br /><br />Anyway...<br />To use this app for your website, you need to install the API component. You may download this from our website at this address:<br /><a href="http://jommobile.com/" target="_blank">http://jommobile.com/</a>'
+ }
+ }
+
+ jQuery('#page-customdialog .dialog-title').html(types[type].title);
+ jQuery('#page-customdialog .dialog-content').html(types[type].content);
+ } catch(e){}
+});
+// Toolbars
+jQuery(document).bind('mobileinit',function(){
+ jQuery.mobile.fixedToolbars.setTouchToggleEnabled(false);
+ jQuery.mobile.listview.prototype.options.filterPlaceholder = 'Filter list...';
+});
+var japp_form_focused = false;
+jQuery('form :input:not(:button, :submit, :reset, :hidden)').live('focus',function(event){
+ japp_form_focused = true;
+ jQuery.mobile.fixedToolbars.hide();
+}).live('blur',function(event){
+ japp_form_focused = false;
+ setTimeout(function(){
+ if ( !japp_form_focused ) {
+ jQuery.mobile.fixedToolbars.show();
+ }
+ }, 25);
+});
+// Fix the textarea height when clicked
+jQuery('textarea').live('click',function(){
+ _fix_textarea_height(jQuery(this));
+});
+// Remove any scroll hooks when a page is changed
+jQuery('.ui-mobile').live('pagebeforehide',function(event, ui){
+ japp.unbind_scroll_listener();
+}).live('pagebeforechange',function(){ // Hide toolbars before page change to avoid clunkyness
+ jQuery.mobile.fixedToolbars.hide();
+}).live('pageshow',function(){
+ jQuery.mobile.fixedToolbars.show();
+});
View
4 www/assets/js/my.conf-sample.js
@@ -0,0 +1,4 @@
+/* Rename this file to my.conf.js */
+japp.api_key = ''; // API key from com_api component
+japp.site_url = 'http://localhost/joomla-app/?option=com_api'; // Path to your Joomla install
+japp.cache = true; // enable/disable caching
View
35 www/categories.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title></title>
+ <link href="assets/css/jquery.mobile-1.0rc2.css" rel="stylesheet" type="text/css" />
+ <link href="assets/css/customSwatch.css" rel="stylesheet" type="text/css" />
+ <script type="text/javascript" charset="utf-8" src="assets/js/jquery-1.6.4.js"></script>
+ <script type="text/javascript" charset="utf-8" src="assets/js/main.js"></script>
+ <script type="text/javascript" charset="utf-8" src="assets/js/jquery.mobile-1.0rc2.js"></script>
+ <script type="text/javascript" charset="utf-8" src="assets/js/jquery.ba-bbq.min.js"></script>
+ <script type="text/javascript" charset="utf-8" src="assets/js/json2.js"></script>
+ <script type="text/javascript" charset="utf-8" src="assets/js/jcache.js"></script>
+ <script type="text/javascript" charset="utf-8" src="assets/js/defaults.js"></script>
+ <script type="text/javascript" charset="utf-8" src="assets/js/my.conf.js"></script>
+</head>
+<body>
+ <div data-role="page" id="page-categories">
+
+ <div data-role="header" data-theme="b" data-position="fixed">
+ <a href="extensions.html" data-rel="back" data-icon="arrow-l">Extensions</a>
+ <h1>Categories</h1>
+ <a href="category.html" data-icon="plus" class="ui-btn-right">New</a>
+ </div><!-- /header -->
+
+ <div data-role="content">
+ <div id="categories-list">
+ <ul data-role="listview" data-filter="true"></ul>
+ </div>
+ </div><!-- /content -->
+ </div><!-- /page -->
+
+</body>
+</html>
View
130 www/category.html
@@ -0,0 +1,130 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title></title>
+ <link href="assets/css/jquery.mobile-1.0rc2.css" rel="stylesheet" type="text/css" />
+ <link href="assets/css/customSwatch.css" rel="stylesheet" type="text/css" />
+ <script type="text/javascript" charset="utf-8" src="assets/js/jquery-1.6.4.js"></script>
+ <script type="text/javascript" charset="utf-8" src="assets/js/main.js"></script>
+ <script type="text/javascript" charset="utf-8" src="assets/js/jquery.mobile-1.0rc2.js"></script>
+ <script type="text/javascript" charset="utf-8" src="assets/js/jquery.ba-bbq.min.js"></script>
+ <script type="text/javascript" charset="utf-8" src="assets/js/json2.js"></script>
+ <script type="text/javascript" charset="utf-8" src="assets/js/jcache.js"></script>
+ <script type="text/javascript" charset="utf-8" src="assets/js/defaults.js"></script>
+ <script type="text/javascript" charset="utf-8" src="assets/js/my.conf.js"></script>
+</head>
+<body>
+ <div data-role="page" id="page-category">
+
+ <div data-role="header" data-theme="b" data-position="fixed">
+ <a href="categories.html" data-rel="back" data-icon="delete">Close</a>
+ <h1 id="page-title"></h1>
+ <a href="javascript:void(0);" data-icon="check" onClick="japp._start_loader('Saving', function(){japp.save_category();});">Save</a>
+ </div><!-- /header -->
+
+ <div data-role="content">
+ <form action="category.html" method="post" data-ajax="false" id="category-form" onSubmit="return false;">
+ <div data-role="fieldcontain">
+ <label for="category-title">Title:</label>
+ <input type="text" name="jform[title]" id="category-title" value="" />
+ </div>
+
+ <div data-role="fieldcontain">
+ <label for="category-alias">Alias: (auto generated)</label>
+ <input type="text" name="jform[alias]" id="category-alias" value="" />
+ </div>
+
+ <div data-role="fieldcontain">
+ <label for="category-parent-id" class="select">Parent:</label>
+ <select name="jform[parent_id]" id="category-parent-id" data-role="none"></select>
+ </div>
+
+ <div data-role="fieldcontain">
+ <label for="category-published">Status:</label>
+ <select name="jform[published]" id="category-published">
+ <option value="1">Published</option>
+ <option value="0">Unpublished</option>
+ <option value="2">Archived</option>
+ <option value="-2">Trash</option>
+ </select>
+ </div>
+
+ <div data-role="fieldcontain">
+ <label for="category-access" class="select">Access:</label>
+ <select name="jform[access]" id="category-access" data-role="none"></select>
+ </div>
+
+ <div data-role="fieldcontain">
+ <label for="category-language" class="select">Language:</label>
+ <select name="jform[language]" id="category-language" data-role="none"></select>
+ </div>
+
+ <div data-role="collapsible" data-collapsed="true">
+ <h3>Content</h3>
+ <textarea cols="50" rows="8" name="jform[description]" id="category-description"></textarea>
+ </div>
+
+ <div data-role="collapsible" data-collapsed="true">
+ <h3>Publishing options</h3>
+
+ <div data-role="fieldcontain">
+ <label for="category-created-user-id">Created by:</label>
+ <select name="jform[created_user_id]" id="category-created-user-id" data-role="none"></select>
+ </div>
+ </div>
+