Commit b48fe667 authored by Pascal Hartig's avatar Pascal Hartig

Backbone+RequireJS: Upgrade to Backbone 1.1

parent 74665360
...@@ -2,9 +2,9 @@ ...@@ -2,9 +2,9 @@
"name": "todomvc-backbone-requirejs", "name": "todomvc-backbone-requirejs",
"version": "0.0.0", "version": "0.0.0",
"dependencies": { "dependencies": {
"backbone": "~0.9.10", "backbone": "~1.1.0",
"underscore": "~1.4.4", "underscore": "~1.5.0",
"jquery": "~1.9.1", "jquery": "~2.0.0",
"todomvc-common": "~0.1.4", "todomvc-common": "~0.1.4",
"backbone.localStorage": "~1.1.0", "backbone.localStorage": "~1.1.0",
"requirejs": "~2.1.5", "requirejs": "~2.1.5",
......
/** /**
* Backbone localStorage Adapter * Backbone localStorage Adapter
* Version 1.1.0 * Version 1.1.7
* *
* https://github.com/jeromegn/Backbone.localStorage * https://github.com/jeromegn/Backbone.localStorage
*/ */
(function (root, factory) { (function (root, factory) {
if (typeof define === "function" && define.amd) { if (typeof exports === 'object' && typeof require === 'function') {
module.exports = factory(require("underscore"), require("backbone"));
} else if (typeof define === "function" && define.amd) {
// AMD. Register as an anonymous module. // AMD. Register as an anonymous module.
define(["underscore","backbone"], function(_, Backbone) { define(["underscore","backbone"], function(_, Backbone) {
// Use global variables if the locals is undefined. // Use global variables if the locals are undefined.
return factory(_ || root._, Backbone || root.Backbone); return factory(_ || root._, Backbone || root.Backbone);
}); });
} else { } else {
// RequireJS isn't being used. Assume underscore and backbone is loaded in <script> tags // RequireJS isn't being used. Assume underscore and backbone are loaded in <script> tags
factory(_, Backbone); factory(_, Backbone);
} }
}(this, function(_, Backbone) { }(this, function(_, Backbone) {
...@@ -37,6 +39,9 @@ function guid() { ...@@ -37,6 +39,9 @@ function guid() {
// with a meaningful name, like the name you'd give a table. // with a meaningful name, like the name you'd give a table.
// window.Store is deprectated, use Backbone.LocalStorage instead // window.Store is deprectated, use Backbone.LocalStorage instead
Backbone.LocalStorage = window.Store = function(name) { Backbone.LocalStorage = window.Store = function(name) {
if( !this.localStorage ) {
throw "Backbone.localStorage: Environment does not support localStorage."
}
this.name = name; this.name = name;
var store = this.localStorage().getItem(this.name); var store = this.localStorage().getItem(this.name);
this.records = (store && store.split(",")) || []; this.records = (store && store.split(",")) || [];
...@@ -77,7 +82,8 @@ _.extend(Backbone.LocalStorage.prototype, { ...@@ -77,7 +82,8 @@ _.extend(Backbone.LocalStorage.prototype, {
// Return the array of all models currently in storage. // Return the array of all models currently in storage.
findAll: function() { findAll: function() {
return _(this.records).chain() // Lodash removed _#chain in v1.0.0-rc.1
return (_.chain || _)(this.records)
.map(function(id){ .map(function(id){
return this.jsonData(this.localStorage().getItem(this.name+"-"+id)); return this.jsonData(this.localStorage().getItem(this.name+"-"+id));
}, this) }, this)
...@@ -104,17 +110,39 @@ _.extend(Backbone.LocalStorage.prototype, { ...@@ -104,17 +110,39 @@ _.extend(Backbone.LocalStorage.prototype, {
// fix for "illegal access" error on Android when JSON.parse is passed null // fix for "illegal access" error on Android when JSON.parse is passed null
jsonData: function (data) { jsonData: function (data) {
return data && JSON.parse(data); return data && JSON.parse(data);
},
// Clear localStorage for specific collection.
_clear: function() {
var local = this.localStorage(),
itemRe = new RegExp("^" + this.name + "-");
// 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); });
this.records.length = 0;
},
// Size of localStorage.
_storageSize: function() {
return this.localStorage().length;
} }
}); });
// localSync delegate to the model or collection's // localSync delegate to the model or collection's
// *localStorage* property, which should be an instance of `Store`. // *localStorage* property, which should be an instance of `Store`.
// window.Store.sync and Backbone.localSync is deprectated, use Backbone.LocalStorage.sync instead // 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) { Backbone.LocalStorage.sync = window.Store.sync = Backbone.localSync = function(method, model, options) {
var store = model.localStorage || model.collection.localStorage; var store = model.localStorage || model.collection.localStorage;
var resp, errorMessage, syncDfd = $.Deferred && $.Deferred(); //If $ is having Deferred - use it. var resp, errorMessage, syncDfd = Backbone.$.Deferred && Backbone.$.Deferred(); //If $ is having Deferred - use it.
try { try {
...@@ -134,21 +162,23 @@ Backbone.LocalStorage.sync = window.Store.sync = Backbone.localSync = function(m ...@@ -134,21 +162,23 @@ Backbone.LocalStorage.sync = window.Store.sync = Backbone.localSync = function(m
} }
} catch(error) { } catch(error) {
if (error.code === DOMException.QUOTA_EXCEEDED_ERR && window.localStorage.length === 0) if (error.code === 22 && store._storageSize() === 0)
errorMessage = "Private browsing is unsupported"; errorMessage = "Private browsing is unsupported";
else else
errorMessage = error.message; errorMessage = error.message;
} }
if (resp) { if (resp) {
if (options && options.success) if (options && options.success) {
if (Backbone.VERSION === "0.9.10") { if (Backbone.VERSION === "0.9.10") {
options.success(model, resp, options); options.success(model, resp, options);
} else { } else {
options.success(resp); options.success(resp);
} }
if (syncDfd) }
if (syncDfd) {
syncDfd.resolve(resp); syncDfd.resolve(resp);
}
} else { } else {
errorMessage = errorMessage ? errorMessage errorMessage = errorMessage ? errorMessage
......
/** /**
* @license RequireJS text 2.0.5 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. * @license RequireJS text 2.0.10 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license. * Available via the MIT or new BSD license.
* see: http://github.com/requirejs/text for details * see: http://github.com/requirejs/text for details
*/ */
/*jslint regexp: true */ /*jslint regexp: true */
/*global require: false, XMLHttpRequest: false, ActiveXObject: false, /*global require, XMLHttpRequest, ActiveXObject,
define: false, window: false, process: false, Packages: false, define, window, process, Packages,
java: false, location: false */ java, location, Components, FileUtils */
define(['module'], function (module) { define(['module'], function (module) {
'use strict'; 'use strict';
var text, fs, var text, fs, Cc, Ci, xpcIsWindows,
progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'], progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'],
xmlRegExp = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, xmlRegExp = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,
bodyRegExp = /<body[^>]*>\s*([\s\S]+)\s*<\/body>/im, bodyRegExp = /<body[^>]*>\s*([\s\S]+)\s*<\/body>/im,
...@@ -19,11 +19,11 @@ define(['module'], function (module) { ...@@ -19,11 +19,11 @@ define(['module'], function (module) {
defaultProtocol = hasLocation && location.protocol && location.protocol.replace(/\:/, ''), defaultProtocol = hasLocation && location.protocol && location.protocol.replace(/\:/, ''),
defaultHostName = hasLocation && location.hostname, defaultHostName = hasLocation && location.hostname,
defaultPort = hasLocation && (location.port || undefined), defaultPort = hasLocation && (location.port || undefined),
buildMap = [], buildMap = {},
masterConfig = (module.config && module.config()) || {}; masterConfig = (module.config && module.config()) || {};
text = { text = {
version: '2.0.5', version: '2.0.10',
strip: function (content) { strip: function (content) {
//Strips <?xml ...?> declarations so that external SVG and XML //Strips <?xml ...?> declarations so that external SVG and XML
...@@ -176,6 +176,12 @@ define(['module'], function (module) { ...@@ -176,6 +176,12 @@ define(['module'], function (module) {
useXhr = (masterConfig.useXhr) || useXhr = (masterConfig.useXhr) ||
text.useXhr; text.useXhr;
// Do not load if it is an empty: url
if (url.indexOf('empty:') === 0) {
onLoad();
return;
}
//Load the text. Use XHR if possible and in a browser. //Load the text. Use XHR if possible and in a browser.
if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) { if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) {
text.get(url, function (content) { text.get(url, function (content) {
...@@ -237,17 +243,22 @@ define(['module'], function (module) { ...@@ -237,17 +243,22 @@ define(['module'], function (module) {
if (masterConfig.env === 'node' || (!masterConfig.env && if (masterConfig.env === 'node' || (!masterConfig.env &&
typeof process !== "undefined" && typeof process !== "undefined" &&
process.versions && process.versions &&
!!process.versions.node)) { !!process.versions.node &&
!process.versions['node-webkit'])) {
//Using special require.nodeRequire, something added by r.js. //Using special require.nodeRequire, something added by r.js.
fs = require.nodeRequire('fs'); fs = require.nodeRequire('fs');
text.get = function (url, callback) { text.get = function (url, callback, errback) {
try {
var file = fs.readFileSync(url, 'utf8'); var file = fs.readFileSync(url, 'utf8');
//Remove BOM (Byte Mark Order) from utf8 files if it is there. //Remove BOM (Byte Mark Order) from utf8 files if it is there.
if (file.indexOf('\uFEFF') === 0) { if (file.indexOf('\uFEFF') === 0) {
file = file.substring(1); file = file.substring(1);
} }
callback(file); callback(file);
} catch (e) {
errback(e);
}
}; };
} else if (masterConfig.env === 'xhr' || (!masterConfig.env && } else if (masterConfig.env === 'xhr' || (!masterConfig.env &&
text.createXhr())) { text.createXhr())) {
...@@ -283,6 +294,10 @@ define(['module'], function (module) { ...@@ -283,6 +294,10 @@ define(['module'], function (module) {
} else { } else {
callback(xhr.responseText); callback(xhr.responseText);
} }
if (masterConfig.onXhrComplete) {
masterConfig.onXhrComplete(xhr, url);
}
} }
}; };
xhr.send(null); xhr.send(null);
...@@ -313,7 +328,9 @@ define(['module'], function (module) { ...@@ -313,7 +328,9 @@ define(['module'], function (module) {
line = line.substring(1); line = line.substring(1);
} }
if (line !== null) {
stringBuffer.append(line); stringBuffer.append(line);
}
while ((line = input.readLine()) !== null) { while ((line = input.readLine()) !== null) {
stringBuffer.append(lineSeparator); stringBuffer.append(lineSeparator);
...@@ -326,7 +343,44 @@ define(['module'], function (module) { ...@@ -326,7 +343,44 @@ define(['module'], function (module) {
} }
callback(content); callback(content);
}; };
} else if (masterConfig.env === 'xpconnect' || (!masterConfig.env &&
typeof Components !== 'undefined' && Components.classes &&
Components.interfaces)) {
//Avert your gaze!
Cc = Components.classes,
Ci = Components.interfaces;
Components.utils['import']('resource://gre/modules/FileUtils.jsm');
xpcIsWindows = ('@mozilla.org/windows-registry-key;1' in Cc);
text.get = function (url, callback) {
var inStream, convertStream, fileObj,
readData = {};
if (xpcIsWindows) {
url = url.replace(/\//g, '\\');
} }
fileObj = new FileUtils.File(url);
//XPCOM, you so crazy
try {
inStream = Cc['@mozilla.org/network/file-input-stream;1']
.createInstance(Ci.nsIFileInputStream);
inStream.init(fileObj, 1, 0, false);
convertStream = Cc['@mozilla.org/intl/converter-input-stream;1']
.createInstance(Ci.nsIConverterInputStream);
convertStream.init(inStream, "utf-8", inStream.available(),
Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
convertStream.readString(inStream.available(), readData);
convertStream.close();
inStream.close();
callback(readData.value);
} catch (e) {
throw new Error((fileObj && fileObj.path || '') + ': ' + e);
}
};
}
return text; return text;
}); });
...@@ -5,7 +5,7 @@ define([ ...@@ -5,7 +5,7 @@ define([
], function (_, Backbone) { ], function (_, Backbone) {
'use strict'; 'use strict';
var TodoModel = Backbone.Model.extend({ var Todo = Backbone.Model.extend({
// Default attributes for the todo // Default attributes for the todo
// and ensure that each todo created has `title` and `completed` keys. // and ensure that each todo created has `title` and `completed` keys.
defaults: { defaults: {
...@@ -21,5 +21,5 @@ define([ ...@@ -21,5 +21,5 @@ define([
} }
}); });
return TodoModel; return Todo;
}); });
...@@ -7,14 +7,14 @@ define([ ...@@ -7,14 +7,14 @@ define([
], function ($, Backbone, Todos, Common) { ], function ($, Backbone, Todos, Common) {
'use strict'; 'use strict';
var Workspace = Backbone.Router.extend({ var TodoRouter = Backbone.Router.extend({
routes: { routes: {
'*filter': 'setFilter' '*filter': 'setFilter'
}, },
setFilter: function (param) { setFilter: function (param) {
// Set the current filter to be used // Set the current filter to be used
Common.TodoFilter = param.trim() || ''; Common.TodoFilter = param || '';
// Trigger a collection filter event, causing hiding/unhiding // Trigger a collection filter event, causing hiding/unhiding
// of the Todo view items // of the Todo view items
...@@ -22,5 +22,5 @@ define([ ...@@ -22,5 +22,5 @@ define([
} }
}); });
return Workspace; return TodoRouter;
}); });
...@@ -10,6 +10,7 @@ define([ ...@@ -10,6 +10,7 @@ define([
], function ($, _, Backbone, Todos, TodoView, statsTemplate, Common) { ], function ($, _, Backbone, Todos, TodoView, statsTemplate, Common) {
'use strict'; 'use strict';
// Our overall **AppView** is the top-level piece of UI.
var AppView = Backbone.View.extend({ var AppView = Backbone.View.extend({
// Instead of generating a new element, bind to the existing skeleton of // Instead of generating a new element, bind to the existing skeleton of
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment