jazz-jss 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Florian Schade
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,19 @@
1
+ = jazz
2
+
3
+ Description goes here.
4
+
5
+ == Contributing to jazz
6
+
7
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
8
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
9
+ * Fork the project
10
+ * Start a feature/bugfix branch
11
+ * Commit and push until you are happy with your contribution
12
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
13
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2011 Florian Schade. See LICENSE.txt for
18
+ further details.
19
+
data/bin/jazz ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
3
+ require 'jazz'
4
+
5
+ if(ARGV.include?('generate'))
6
+ Jazz::CLI.start
7
+ else
8
+ Jazz::AppGenerator.start
9
+ end
@@ -0,0 +1,390 @@
1
+ /*!
2
+ * jQuery hashchange event - v1.3 - 7/21/2010
3
+ * http://benalman.com/projects/jquery-hashchange-plugin/
4
+ *
5
+ * Copyright (c) 2010 "Cowboy" Ben Alman
6
+ * Dual licensed under the MIT and GPL licenses.
7
+ * http://benalman.com/about/license/
8
+ */
9
+
10
+ // Script: jQuery hashchange event
11
+ //
12
+ // *Version: 1.3, Last updated: 7/21/2010*
13
+ //
14
+ // Project Home - http://benalman.com/projects/jquery-hashchange-plugin/
15
+ // GitHub - http://github.com/cowboy/jquery-hashchange/
16
+ // Source - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.js
17
+ // (Minified) - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.min.js (0.8kb gzipped)
18
+ //
19
+ // About: License
20
+ //
21
+ // Copyright (c) 2010 "Cowboy" Ben Alman,
22
+ // Dual licensed under the MIT and GPL licenses.
23
+ // http://benalman.com/about/license/
24
+ //
25
+ // About: Examples
26
+ //
27
+ // These working examples, complete with fully commented code, illustrate a few
28
+ // ways in which this plugin can be used.
29
+ //
30
+ // hashchange event - http://benalman.com/code/projects/jquery-hashchange/examples/hashchange/
31
+ // document.domain - http://benalman.com/code/projects/jquery-hashchange/examples/document_domain/
32
+ //
33
+ // About: Support and Testing
34
+ //
35
+ // Information about what version or versions of jQuery this plugin has been
36
+ // tested with, what browsers it has been tested in, and where the unit tests
37
+ // reside (so you can test it yourself).
38
+ //
39
+ // jQuery Versions - 1.2.6, 1.3.2, 1.4.1, 1.4.2
40
+ // Browsers Tested - Internet Explorer 6-8, Firefox 2-4, Chrome 5-6, Safari 3.2-5,
41
+ // Opera 9.6-10.60, iPhone 3.1, Android 1.6-2.2, BlackBerry 4.6-5.
42
+ // Unit Tests - http://benalman.com/code/projects/jquery-hashchange/unit/
43
+ //
44
+ // About: Known issues
45
+ //
46
+ // While this jQuery hashchange event implementation is quite stable and
47
+ // robust, there are a few unfortunate browser bugs surrounding expected
48
+ // hashchange event-based behaviors, independent of any JavaScript
49
+ // window.onhashchange abstraction. See the following examples for more
50
+ // information:
51
+ //
52
+ // Chrome: Back Button - http://benalman.com/code/projects/jquery-hashchange/examples/bug-chrome-back-button/
53
+ // Firefox: Remote XMLHttpRequest - http://benalman.com/code/projects/jquery-hashchange/examples/bug-firefox-remote-xhr/
54
+ // WebKit: Back Button in an Iframe - http://benalman.com/code/projects/jquery-hashchange/examples/bug-webkit-hash-iframe/
55
+ // Safari: Back Button from a different domain - http://benalman.com/code/projects/jquery-hashchange/examples/bug-safari-back-from-diff-domain/
56
+ //
57
+ // Also note that should a browser natively support the window.onhashchange
58
+ // event, but not report that it does, the fallback polling loop will be used.
59
+ //
60
+ // About: Release History
61
+ //
62
+ // 1.3 - (7/21/2010) Reorganized IE6/7 Iframe code to make it more
63
+ // "removable" for mobile-only development. Added IE6/7 document.title
64
+ // support. Attempted to make Iframe as hidden as possible by using
65
+ // techniques from http://www.paciellogroup.com/blog/?p=604. Added
66
+ // support for the "shortcut" format $(window).hashchange( fn ) and
67
+ // $(window).hashchange() like jQuery provides for built-in events.
68
+ // Renamed jQuery.hashchangeDelay to <jQuery.fn.hashchange.delay> and
69
+ // lowered its default value to 50. Added <jQuery.fn.hashchange.domain>
70
+ // and <jQuery.fn.hashchange.src> properties plus document-domain.html
71
+ // file to address access denied issues when setting document.domain in
72
+ // IE6/7.
73
+ // 1.2 - (2/11/2010) Fixed a bug where coming back to a page using this plugin
74
+ // from a page on another domain would cause an error in Safari 4. Also,
75
+ // IE6/7 Iframe is now inserted after the body (this actually works),
76
+ // which prevents the page from scrolling when the event is first bound.
77
+ // Event can also now be bound before DOM ready, but it won't be usable
78
+ // before then in IE6/7.
79
+ // 1.1 - (1/21/2010) Incorporated document.documentMode test to fix IE8 bug
80
+ // where browser version is incorrectly reported as 8.0, despite
81
+ // inclusion of the X-UA-Compatible IE=EmulateIE7 meta tag.
82
+ // 1.0 - (1/9/2010) Initial Release. Broke out the jQuery BBQ event.special
83
+ // window.onhashchange functionality into a separate plugin for users
84
+ // who want just the basic event & back button support, without all the
85
+ // extra awesomeness that BBQ provides. This plugin will be included as
86
+ // part of jQuery BBQ, but also be available separately.
87
+
88
+ (function($,window,undefined){
89
+ '$:nomunge'; // Used by YUI compressor.
90
+
91
+ // Reused string.
92
+ var str_hashchange = 'hashchange',
93
+
94
+ // Method / object references.
95
+ doc = document,
96
+ fake_onhashchange,
97
+ special = $.event.special,
98
+
99
+ // Does the browser support window.onhashchange? Note that IE8 running in
100
+ // IE7 compatibility mode reports true for 'onhashchange' in window, even
101
+ // though the event isn't supported, so also test document.documentMode.
102
+ doc_mode = doc.documentMode,
103
+ supports_onhashchange = 'on' + str_hashchange in window && ( doc_mode === undefined || doc_mode > 7 );
104
+
105
+ // Get location.hash (or what you'd expect location.hash to be) sans any
106
+ // leading #. Thanks for making this necessary, Firefox!
107
+ function get_fragment( url ) {
108
+ url = url || location.href;
109
+ return '#' + url.replace( /^[^#]*#?(.*)$/, '$1' );
110
+ };
111
+
112
+ // Method: jQuery.fn.hashchange
113
+ //
114
+ // Bind a handler to the window.onhashchange event or trigger all bound
115
+ // window.onhashchange event handlers. This behavior is consistent with
116
+ // jQuery's built-in event handlers.
117
+ //
118
+ // Usage:
119
+ //
120
+ // > jQuery(window).hashchange( [ handler ] );
121
+ //
122
+ // Arguments:
123
+ //
124
+ // handler - (Function) Optional handler to be bound to the hashchange
125
+ // event. This is a "shortcut" for the more verbose form:
126
+ // jQuery(window).bind( 'hashchange', handler ). If handler is omitted,
127
+ // all bound window.onhashchange event handlers will be triggered. This
128
+ // is a shortcut for the more verbose
129
+ // jQuery(window).trigger( 'hashchange' ). These forms are described in
130
+ // the <hashchange event> section.
131
+ //
132
+ // Returns:
133
+ //
134
+ // (jQuery) The initial jQuery collection of elements.
135
+
136
+ // Allow the "shortcut" format $(elem).hashchange( fn ) for binding and
137
+ // $(elem).hashchange() for triggering, like jQuery does for built-in events.
138
+ $.fn[ str_hashchange ] = function( fn ) {
139
+ return fn ? this.bind( str_hashchange, fn ) : this.trigger( str_hashchange );
140
+ };
141
+
142
+ // Property: jQuery.fn.hashchange.delay
143
+ //
144
+ // The numeric interval (in milliseconds) at which the <hashchange event>
145
+ // polling loop executes. Defaults to 50.
146
+
147
+ // Property: jQuery.fn.hashchange.domain
148
+ //
149
+ // If you're setting document.domain in your JavaScript, and you want hash
150
+ // history to work in IE6/7, not only must this property be set, but you must
151
+ // also set document.domain BEFORE jQuery is loaded into the page. This
152
+ // property is only applicable if you are supporting IE6/7 (or IE8 operating
153
+ // in "IE7 compatibility" mode).
154
+ //
155
+ // In addition, the <jQuery.fn.hashchange.src> property must be set to the
156
+ // path of the included "document-domain.html" file, which can be renamed or
157
+ // modified if necessary (note that the document.domain specified must be the
158
+ // same in both your main JavaScript as well as in this file).
159
+ //
160
+ // Usage:
161
+ //
162
+ // jQuery.fn.hashchange.domain = document.domain;
163
+
164
+ // Property: jQuery.fn.hashchange.src
165
+ //
166
+ // If, for some reason, you need to specify an Iframe src file (for example,
167
+ // when setting document.domain as in <jQuery.fn.hashchange.domain>), you can
168
+ // do so using this property. Note that when using this property, history
169
+ // won't be recorded in IE6/7 until the Iframe src file loads. This property
170
+ // is only applicable if you are supporting IE6/7 (or IE8 operating in "IE7
171
+ // compatibility" mode).
172
+ //
173
+ // Usage:
174
+ //
175
+ // jQuery.fn.hashchange.src = 'path/to/file.html';
176
+
177
+ $.fn[ str_hashchange ].delay = 50;
178
+ /*
179
+ $.fn[ str_hashchange ].domain = null;
180
+ $.fn[ str_hashchange ].src = null;
181
+ */
182
+
183
+ // Event: hashchange event
184
+ //
185
+ // Fired when location.hash changes. In browsers that support it, the native
186
+ // HTML5 window.onhashchange event is used, otherwise a polling loop is
187
+ // initialized, running every <jQuery.fn.hashchange.delay> milliseconds to
188
+ // see if the hash has changed. In IE6/7 (and IE8 operating in "IE7
189
+ // compatibility" mode), a hidden Iframe is created to allow the back button
190
+ // and hash-based history to work.
191
+ //
192
+ // Usage as described in <jQuery.fn.hashchange>:
193
+ //
194
+ // > // Bind an event handler.
195
+ // > jQuery(window).hashchange( function(e) {
196
+ // > var hash = location.hash;
197
+ // > ...
198
+ // > });
199
+ // >
200
+ // > // Manually trigger the event handler.
201
+ // > jQuery(window).hashchange();
202
+ //
203
+ // A more verbose usage that allows for event namespacing:
204
+ //
205
+ // > // Bind an event handler.
206
+ // > jQuery(window).bind( 'hashchange', function(e) {
207
+ // > var hash = location.hash;
208
+ // > ...
209
+ // > });
210
+ // >
211
+ // > // Manually trigger the event handler.
212
+ // > jQuery(window).trigger( 'hashchange' );
213
+ //
214
+ // Additional Notes:
215
+ //
216
+ // * The polling loop and Iframe are not created until at least one handler
217
+ // is actually bound to the 'hashchange' event.
218
+ // * If you need the bound handler(s) to execute immediately, in cases where
219
+ // a location.hash exists on page load, via bookmark or page refresh for
220
+ // example, use jQuery(window).hashchange() or the more verbose
221
+ // jQuery(window).trigger( 'hashchange' ).
222
+ // * The event can be bound before DOM ready, but since it won't be usable
223
+ // before then in IE6/7 (due to the necessary Iframe), recommended usage is
224
+ // to bind it inside a DOM ready handler.
225
+
226
+ // Override existing $.event.special.hashchange methods (allowing this plugin
227
+ // to be defined after jQuery BBQ in BBQ's source code).
228
+ special[ str_hashchange ] = $.extend( special[ str_hashchange ], {
229
+
230
+ // Called only when the first 'hashchange' event is bound to window.
231
+ setup: function() {
232
+ // If window.onhashchange is supported natively, there's nothing to do..
233
+ if ( supports_onhashchange ) { return false; }
234
+
235
+ // Otherwise, we need to create our own. And we don't want to call this
236
+ // until the user binds to the event, just in case they never do, since it
237
+ // will create a polling loop and possibly even a hidden Iframe.
238
+ $( fake_onhashchange.start );
239
+ },
240
+
241
+ // Called only when the last 'hashchange' event is unbound from window.
242
+ teardown: function() {
243
+ // If window.onhashchange is supported natively, there's nothing to do..
244
+ if ( supports_onhashchange ) { return false; }
245
+
246
+ // Otherwise, we need to stop ours (if possible).
247
+ $( fake_onhashchange.stop );
248
+ }
249
+
250
+ });
251
+
252
+ // fake_onhashchange does all the work of triggering the window.onhashchange
253
+ // event for browsers that don't natively support it, including creating a
254
+ // polling loop to watch for hash changes and in IE 6/7 creating a hidden
255
+ // Iframe to enable back and forward.
256
+ fake_onhashchange = (function(){
257
+ var self = {},
258
+ timeout_id,
259
+
260
+ // Remember the initial hash so it doesn't get triggered immediately.
261
+ last_hash = get_fragment(),
262
+
263
+ fn_retval = function(val){ return val; },
264
+ history_set = fn_retval,
265
+ history_get = fn_retval;
266
+
267
+ // Start the polling loop.
268
+ self.start = function() {
269
+ timeout_id || poll();
270
+ };
271
+
272
+ // Stop the polling loop.
273
+ self.stop = function() {
274
+ timeout_id && clearTimeout( timeout_id );
275
+ timeout_id = undefined;
276
+ };
277
+
278
+ // This polling loop checks every $.fn.hashchange.delay milliseconds to see
279
+ // if location.hash has changed, and triggers the 'hashchange' event on
280
+ // window when necessary.
281
+ function poll() {
282
+ var hash = get_fragment(),
283
+ history_hash = history_get( last_hash );
284
+
285
+ if ( hash !== last_hash ) {
286
+ history_set( last_hash = hash, history_hash );
287
+
288
+ $(window).trigger( str_hashchange );
289
+
290
+ } else if ( history_hash !== last_hash ) {
291
+ location.href = location.href.replace( /#.*/, '' ) + history_hash;
292
+ }
293
+
294
+ timeout_id = setTimeout( poll, $.fn[ str_hashchange ].delay );
295
+ };
296
+
297
+ // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
298
+ // vvvvvvvvvvvvvvvvvvv REMOVE IF NOT SUPPORTING IE6/7/8 vvvvvvvvvvvvvvvvvvv
299
+ // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
300
+ $.browser.msie && !supports_onhashchange && (function(){
301
+ // Not only do IE6/7 need the "magical" Iframe treatment, but so does IE8
302
+ // when running in "IE7 compatibility" mode.
303
+
304
+ var iframe,
305
+ iframe_src;
306
+
307
+ // When the event is bound and polling starts in IE 6/7, create a hidden
308
+ // Iframe for history handling.
309
+ self.start = function(){
310
+ if ( !iframe ) {
311
+ iframe_src = $.fn[ str_hashchange ].src;
312
+ iframe_src = iframe_src && iframe_src + get_fragment();
313
+
314
+ // Create hidden Iframe. Attempt to make Iframe as hidden as possible
315
+ // by using techniques from http://www.paciellogroup.com/blog/?p=604.
316
+ iframe = $('<iframe tabindex="-1" title="empty"/>').hide()
317
+
318
+ // When Iframe has completely loaded, initialize the history and
319
+ // start polling.
320
+ .one( 'load', function(){
321
+ iframe_src || history_set( get_fragment() );
322
+ poll();
323
+ })
324
+
325
+ // Load Iframe src if specified, otherwise nothing.
326
+ .attr( 'src', iframe_src || 'javascript:0' )
327
+
328
+ // Append Iframe after the end of the body to prevent unnecessary
329
+ // initial page scrolling (yes, this works).
330
+ .insertAfter( 'body' )[0].contentWindow;
331
+
332
+ // Whenever `document.title` changes, update the Iframe's title to
333
+ // prettify the back/next history menu entries. Since IE sometimes
334
+ // errors with "Unspecified error" the very first time this is set
335
+ // (yes, very useful) wrap this with a try/catch block.
336
+ doc.onpropertychange = function(){
337
+ try {
338
+ if ( event.propertyName === 'title' ) {
339
+ iframe.document.title = doc.title;
340
+ }
341
+ } catch(e) {}
342
+ };
343
+
344
+ }
345
+ };
346
+
347
+ // Override the "stop" method since an IE6/7 Iframe was created. Even
348
+ // if there are no longer any bound event handlers, the polling loop
349
+ // is still necessary for back/next to work at all!
350
+ self.stop = fn_retval;
351
+
352
+ // Get history by looking at the hidden Iframe's location.hash.
353
+ history_get = function() {
354
+ return get_fragment( iframe.location.href );
355
+ };
356
+
357
+ // Set a new history item by opening and then closing the Iframe
358
+ // document, *then* setting its location.hash. If document.domain has
359
+ // been set, update that as well.
360
+ history_set = function( hash, history_hash ) {
361
+ var iframe_doc = iframe.document,
362
+ domain = $.fn[ str_hashchange ].domain;
363
+
364
+ if ( hash !== history_hash ) {
365
+ // Update Iframe with any initial `document.title` that might be set.
366
+ iframe_doc.title = doc.title;
367
+
368
+ // Opening the Iframe's document after it has been closed is what
369
+ // actually adds a history entry.
370
+ iframe_doc.open();
371
+
372
+ // Set document.domain for the Iframe document as well, if necessary.
373
+ domain && iframe_doc.write( '<script>document.domain="' + domain + '"</script>' );
374
+
375
+ iframe_doc.close();
376
+
377
+ // Update the Iframe's hash, for great justice.
378
+ iframe.location.hash = hash;
379
+ }
380
+ };
381
+
382
+ })();
383
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
384
+ // ^^^^^^^^^^^^^^^^^^^ REMOVE IF NOT SUPPORTING IE6/7/8 ^^^^^^^^^^^^^^^^^^^
385
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
386
+
387
+ return self;
388
+ })();
389
+
390
+ })(jQuery,this);
@@ -0,0 +1,17 @@
1
+ Jazz.Controller = function () {
2
+ this.initialize();
3
+ };
4
+
5
+ Jazz.Controller.extend = Jazz.Controller.create = Jazz.Helper.extend;
6
+
7
+ _.extend(
8
+ Jazz.Controller.prototype,
9
+ {
10
+ index:function () {},
11
+ create:function () {},
12
+ update:function () {},
13
+ remove:function () {},
14
+ initialize:function () {}
15
+
16
+ }
17
+ );
@@ -0,0 +1,41 @@
1
+ Jazz.Db = function () {
2
+ this._prepare();
3
+ }
4
+
5
+ Jazz.Db.extend = Jazz.Db.create = Jazz.Helper.extend;
6
+
7
+ _.extend(
8
+ Jazz.Db.prototype,
9
+ {
10
+ //
11
+ _prepare:function () {
12
+ //Resets the attributes per OBJ
13
+ this.models = {};
14
+ },
15
+
16
+ add:function (model) {
17
+ obj = jQuery.extend(true, {}, model);
18
+ obj._config.persist = true;
19
+ this.models[obj.uid()] = obj;
20
+ },
21
+
22
+ all:function () {
23
+ return this.models;
24
+ },
25
+
26
+ first:function () {
27
+ return _.first(this.models);
28
+ },
29
+
30
+ findBy:function (query) {
31
+ var objs = [];
32
+ _.each(
33
+ this.models,
34
+ function (model) {
35
+ if (model.hasPropertiesWithValues(query)) objs.push(model);
36
+ }
37
+ );
38
+ return objs
39
+ }
40
+ }
41
+ );
@@ -0,0 +1,55 @@
1
+ _.extend(
2
+ Jazz.Helper,
3
+ {
4
+ loadView: function (name) {
5
+ return $.ajax({
6
+ url:'./app/assets/templates/' + name + '.html',
7
+ type:'GET',
8
+ cache:false,
9
+ async:false
10
+ }).responseText;
11
+ },
12
+ extend: function (protoProps, classProps) {
13
+ var child = Jazz.Helper.inherits(this, protoProps, classProps);
14
+ //var child = jQuery.extend(true, this, protoProps, classProps);
15
+ child.extend = this.extend;
16
+ return child;
17
+ },
18
+
19
+ ctor: function(){},
20
+
21
+ inherits: function(parent, protoProps, staticProps) {
22
+ var child;
23
+ if (protoProps && protoProps.hasOwnProperty('constructor')) {
24
+ child = protoProps.constructor;
25
+ } else {
26
+ child = function(){ return parent.apply(this, arguments); };
27
+ }
28
+
29
+ _.extend(child, parent);
30
+
31
+ Jazz.Helper.ctor.prototype = parent.prototype;
32
+ child.prototype = new Jazz.Helper.ctor();
33
+
34
+ if (protoProps) _.extend(child.prototype, protoProps);
35
+
36
+ if (staticProps) _.extend(child, staticProps);
37
+
38
+ child.prototype.constructor = child;
39
+
40
+ child.__super__ = parent.prototype;
41
+
42
+ return child;
43
+ },
44
+
45
+ showError: function (message) {
46
+ alert(message);
47
+ },
48
+
49
+ getApp: function(){
50
+ return eval(Jazz.Config.appName);
51
+ }
52
+
53
+ }
54
+ );
55
+
@@ -0,0 +1,122 @@
1
+ Jazz.Model = function(attributes, options){
2
+
3
+ this._prepare(attributes);
4
+ this.initialize();
5
+ };
6
+
7
+ Jazz.Model.extend = Jazz.Model.create = Jazz.Helper.extend;
8
+
9
+ _.extend(
10
+ Jazz.Model.prototype,
11
+ {
12
+ //initialize function
13
+ initialize: function(){},
14
+
15
+ //
16
+ _prepare: function(attributes){
17
+
18
+ //Resets the attributes per OBJ
19
+ this.attributes = {};
20
+
21
+ //Resets the _config and combine per OBJ
22
+ _config = {
23
+ uid: _.uniqueId(),
24
+ persist: false
25
+ }
26
+ this._config = _.extend({}, this._config, _config);
27
+
28
+ //Prepopulate OBJ
29
+ defaults = {};
30
+
31
+ for(var attr in window[this._config.table].columns){
32
+ defaults[attr] = window[this._config.table].columns[attr].value;
33
+ }
34
+
35
+ _.extend(defaults, attributes);
36
+
37
+ this.set(defaults);
38
+
39
+ },
40
+
41
+ //
42
+ toJson : function() {
43
+ return _.clone(this.attributes);
44
+ },
45
+
46
+ //
47
+ has : function(attr) {
48
+ return this.attributes[attr] != null;
49
+ },
50
+
51
+ //
52
+ hasPropertiesWithValues : function(query) {
53
+
54
+ size = _.size(query);
55
+ i = 0;
56
+
57
+ for (var key in query) {
58
+ if (!this.has(key)) continue;
59
+ if (this.get(key) != query[key]) continue;
60
+ i++;
61
+ }
62
+
63
+ return i == size ? true : false;
64
+
65
+ },
66
+
67
+ //
68
+ set: function(attrs){
69
+ if (!attrs) return this;
70
+
71
+ var now = this.attributes;
72
+ var can = _.keys(window[this._config.table].columns);
73
+
74
+ for (var attr in attrs) {
75
+ if (_.contains(can, attr) ) {
76
+ now[attr] = attrs[attr];
77
+ } else {
78
+ Jazz.Helper.showError('Cannot add ' + attr);
79
+ }
80
+ }
81
+
82
+ return this;
83
+ },
84
+
85
+ //
86
+ get: function(key){
87
+ if (!this.attributes) return this;
88
+ if (!key) return this.attributes;
89
+ return this.attributes[key];
90
+ },
91
+
92
+ uid: function(){
93
+ return this._config.uid;
94
+ },
95
+
96
+ //
97
+ remove: function(key){
98
+ if (!key) return this;
99
+ delete this.attributes[key];
100
+ return this;
101
+ },
102
+
103
+ //
104
+ create: function(attributes){
105
+ this.validate.atCreate();
106
+ this.set(attributes);
107
+ window[this._config.table].add(this);
108
+ },
109
+
110
+ update: function(attributes){
111
+ this.validate.atUpdate();
112
+ this.set(attributes);
113
+ window[this._config.table].add(this);
114
+ },
115
+
116
+ validate: {
117
+ atCreate: function(){},
118
+ atUpdate: function(){},
119
+ }
120
+
121
+ }
122
+ );