Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.idea
bower_components
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
MarionetteJS + RequireJS + Twitter Bootstrap
=============================================================

Let's start the dance! This boilerplate is a ready setup for starting your next awesome javascript app in minutes.

This setup includes -
Expand All @@ -10,6 +9,10 @@ This setup includes -
* RequireJS (AMD)
* Twitter Bootstrap (3.1.1)

Here is a [live demo](http://ajaxray.com/demo/marionette-boilerplate) of this setup.
Here is a [live demo, using original marionette.js 1.0.4](http://ajaxray.com/demo/marionette-boilerplate) of this setup.

**Quick start**

**Batteries included!** You can just get it and start coding instantly. There is no dependency on any other tool or library to get started.
clone this repo
cd marionette-boilerplate
bower install
10 changes: 5 additions & 5 deletions bower.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
"name": "todomvc-backbone_marionette_require",
"version": "0.0.0",
"dependencies": {
"todomvc-common": "~0.1.6",
"requirejs": "~2.1.6",
"underscore": "~1.4.4",
"backbone.marionette": "~1.0.3",
"backbone.localStorage": "~1.1.4"
"todomvc-common": "latest",
"requirejs": "latest",
"underscore": "latest",
"backbone.marionette": "latest",
"backbone.localStorage": "latest"
}
}
138 changes: 87 additions & 51 deletions bower_components/backbone.localStorage/backbone.localStorage.js
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
/**
* Backbone localStorage Adapter
* Version 1.1.4
* Version 1.1.14
*
* https://github.com/jeromegn/Backbone.localStorage
*/
(function (root, factory) {
if (typeof exports === 'object') {
module.exports = factory(require("underscore"), require("backbone"));
} else if (typeof define === "function" && define.amd) {
// AMD. Register as an anonymous module.
define(["underscore","backbone"], function(_, Backbone) {
// Use global variables if the locals are undefined.
return factory(_ || root._, Backbone || root.Backbone);
});
} else {
// RequireJS isn't being used. Assume underscore and backbone are loaded in <script> tags
factory(_, Backbone);
}
}(this, function(_, Backbone) {
if (typeof exports === 'object' && typeof require === 'function') {
module.exports = factory(require("backbone"));
} else if (typeof define === "function" && define.amd) {
// AMD. Register as an anonymous module.
define(["backbone"], function(Backbone) {
// Use global variables if the locals are undefined.
return factory(Backbone || root.Backbone);
});
} else {
factory(Backbone);
}
}(this, function(Backbone) {
// A simple module to replace `Backbone.sync` with *localStorage*-based
// persistence. Models are given GUIDS, and saved into a JSON object. Simple
// as that.

// Hold reference to Underscore.js and Backbone.js in the closure in order
// to make things work even if they are removed from the global namespace

// Generate four random hex digits.
function S4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
Expand All @@ -35,19 +31,49 @@ function guid() {
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
};

function isObject(item) {
return item === Object(item);
}

function contains(array, item) {
var i = array.length;
while (i--) if (array[i] === item) return true;
return false;
}

function extend(obj, props) {
for (var key in props) obj[key] = props[key]
return obj;
}

function result(object, property) {
if (object == null) return void 0;
var value = object[property];
return (typeof value === 'function') ? object[property]() : value;
}

// Our Store is represented by a single JS object in *localStorage*. Create it
// with a meaningful name, like the name you'd give a table.
// window.Store is deprectated, use Backbone.LocalStorage instead
Backbone.LocalStorage = window.Store = function(name) {
Backbone.LocalStorage = window.Store = function(name, serializer) {
if( !this.localStorage ) {
throw "Backbone.localStorage: Environment does not support localStorage."
}
this.name = name;
this.serializer = serializer || {
serialize: function(item) {
return isObject(item) ? JSON.stringify(item) : item;
},
// fix for "illegal access" error on Android when JSON.parse is passed null
deserialize: function (data) {
return data && JSON.parse(data);
}
};
var store = this.localStorage().getItem(this.name);
this.records = (store && store.split(",")) || [];
};

_.extend(Backbone.LocalStorage.prototype, {
extend(Backbone.LocalStorage.prototype, {

// Save the current state of the **Store** to *localStorage*.
save: function() {
Expand All @@ -57,48 +83,52 @@ _.extend(Backbone.LocalStorage.prototype, {
// Add a model, giving it a (hopefully)-unique GUID, if it doesn't already
// have an id of it's own.
create: function(model) {
if (!model.id) {
if (!model.id && model.id !== 0) {
model.id = guid();
model.set(model.idAttribute, model.id);
}
this.localStorage().setItem(this.name+"-"+model.id, JSON.stringify(model));
this.localStorage().setItem(this._itemName(model.id), this.serializer.serialize(model));
this.records.push(model.id.toString());
this.save();
return this.find(model);
},

// Update a model by replacing its copy in `this.data`.
update: function(model) {
this.localStorage().setItem(this.name+"-"+model.id, JSON.stringify(model));
if (!_.include(this.records, model.id.toString()))
this.records.push(model.id.toString()); this.save();
this.localStorage().setItem(this._itemName(model.id), this.serializer.serialize(model));
var modelId = model.id.toString();
if (!contains(this.records, modelId)) {
this.records.push(modelId);
this.save();
}
return this.find(model);
},

// Retrieve a model from `this.data` by id.
find: function(model) {
return this.jsonData(this.localStorage().getItem(this.name+"-"+model.id));
return this.serializer.deserialize(this.localStorage().getItem(this._itemName(model.id)));
},

// Return the array of all models currently in storage.
findAll: function() {
// Lodash removed _#chain in v1.0.0-rc.1
return (_.chain || _)(this.records)
.map(function(id){
return this.jsonData(this.localStorage().getItem(this.name+"-"+id));
}, this)
.compact()
.value();
var result = [];
for (var i = 0, id, data; i < this.records.length; i++) {
id = this.records[i];
data = this.serializer.deserialize(this.localStorage().getItem(this._itemName(id)));
if (data != null) result.push(data);
}
return result;
},

// Delete a model from `this.data`, returning it.
destroy: function(model) {
if (model.isNew())
return false
this.localStorage().removeItem(this.name+"-"+model.id);
this.records = _.reject(this.records, function(id){
return id === model.id.toString();
});
this.localStorage().removeItem(this._itemName(model.id));
var modelId = model.id.toString();
for (var i = 0, id; i < this.records.length; i++) {
if (this.records[i] === modelId) {
this.records.splice(i, 1);
}
}
this.save();
return model;
},
Expand All @@ -107,11 +137,6 @@ _.extend(Backbone.LocalStorage.prototype, {
return localStorage;
},

// fix for "illegal access" error on Android when JSON.parse is passed null
jsonData: function (data) {
return data && JSON.parse(data);
},

// Clear localStorage for specific collection.
_clear: function() {
var local = this.localStorage(),
Expand All @@ -120,16 +145,23 @@ _.extend(Backbone.LocalStorage.prototype, {
// Remove id-tracking item (e.g., "foo").
local.removeItem(this.name);

// Lodash removed _#chain in v1.0.0-rc.1
// Match all data items (e.g., "foo-ID") and remove.
(_.chain || _)(local).keys()
.filter(function (k) { return itemRe.test(k); })
.each(function (k) { local.removeItem(k); });
for (var k in local) {
if (itemRe.test(k)) {
local.removeItem(k);
}
}

this.records.length = 0;
},

// Size of localStorage.
_storageSize: function() {
return this.localStorage().length;
},

_itemName: function(id) {
return this.name+"-"+id;
}

});
Expand All @@ -138,9 +170,13 @@ _.extend(Backbone.LocalStorage.prototype, {
// *localStorage* property, which should be an instance of `Store`.
// window.Store.sync and Backbone.localSync is deprecated, use Backbone.LocalStorage.sync instead
Backbone.LocalStorage.sync = window.Store.sync = Backbone.localSync = function(method, model, options) {
var store = model.localStorage || model.collection.localStorage;
var store = result(model, 'localStorage') || result(model.collection, 'localStorage');

var resp, errorMessage, syncDfd = Backbone.$.Deferred && Backbone.$.Deferred(); //If $ is having Deferred - use it.
var resp, errorMessage;
//If $ is having Deferred - use it.
var syncDfd = Backbone.$ ?
(Backbone.$.Deferred && Backbone.$.Deferred()) :
(Backbone.Deferred && Backbone.Deferred());

try {

Expand All @@ -160,7 +196,7 @@ Backbone.LocalStorage.sync = window.Store.sync = Backbone.localSync = function(m
}

} catch(error) {
if (error.code === DOMException.QUOTA_EXCEEDED_ERR && store._storageSize() === 0)
if (error.code === 22 && store._storageSize() === 0)
errorMessage = "Private browsing is unsupported";
else
errorMessage = error.message;
Expand All @@ -177,7 +213,7 @@ Backbone.LocalStorage.sync = window.Store.sync = Backbone.localSync = function(m
if (syncDfd) {
syncDfd.resolve(resp);
}

} else {
errorMessage = errorMessage ? errorMessage
: "Record Not Found";
Expand Down
Loading