1
0
Fork 0

Re-added faulty dir

master
Matthieu Lalonde 12 years ago
parent 9e3e88914f
commit d9d63ddf7b

@ -0,0 +1,6 @@
test:
open tests/test.html
open tests/test2.html
minified:
uglifyjs -o backbone.localStorage-min.js backbone.localStorage.js

@ -0,0 +1,71 @@
# Backbone localStorage Adapter v1.0
[![Build Status](https://secure.travis-ci.org/jeromegn/Backbone.localStorage.png?branch=master)](http://travis-ci.org/jeromegn/Backbone.localStorage)
Quite simply a localStorage adapter for Backbone. It's a drop-in replacement for Backbone.Sync() to handle saving to a localStorage database.
## Usage
Include Backbone.localStorage after having included Backbone.js:
```html
<script type="text/javascript" src="backbone.js"></script>
<script type="text/javascript" src="backbone.localStorage.js"></script>
```
Create your collections like so:
```javascript
window.SomeCollection = Backbone.Collection.extend({
localStorage: new Backbone.LocalStorage("SomeCollection"), // Unique name within your app.
// ... everything else is normal.
});
```
Feel free to use Backbone as you usually would, this is a drop-in replacement.
## Contributing
You'll need node and to `npm install` before being able to run the minification script.
1. Fork;
2. Write code;
3. Write tests (or vice et versa);
4. `make test`;
5. `make minified`;
6. Create a pull request.
Have fun!
## Credits
Thanks to [Mark Woodall](https://github.com/llad) for the QUnit tests.
Thanks to [Martin Häcker](https://github.com/dwt) for the many fixes and the test isolation.
## Licensed
Licensed under MIT license
Copyright (c) 2010 Jerome Gravel-Niquet
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -0,0 +1,4 @@
/**
* Backbone localStorage Adapter
* https://github.com/jeromegn/Backbone.localStorage
*/(function(){function c(){return((1+Math.random())*65536|0).toString(16).substring(1)}function d(){return c()+c()+"-"+c()+"-"+c()+"-"+c()+"-"+c()+c()+c()}var a=this._,b=this.Backbone;b.LocalStorage=window.Store=function(a){this.name=a;var b=this.localStorage().getItem(this.name);this.records=b&&b.split(",")||[]},a.extend(b.LocalStorage.prototype,{save:function(){this.localStorage().setItem(this.name,this.records.join(","))},create:function(a){return a.id||(a.id=d(),a.set(a.idAttribute,a.id)),this.localStorage().setItem(this.name+"-"+a.id,JSON.stringify(a)),this.records.push(a.id.toString()),this.save(),a.toJSON()},update:function(b){return this.localStorage().setItem(this.name+"-"+b.id,JSON.stringify(b)),a.include(this.records,b.id.toString())||this.records.push(b.id.toString()),this.save(),b.toJSON()},find:function(a){return JSON.parse(this.localStorage().getItem(this.name+"-"+a.id))},findAll:function(){return a(this.records).chain().map(function(a){return JSON.parse(this.localStorage().getItem(this.name+"-"+a))},this).compact().value()},destroy:function(b){return this.localStorage().removeItem(this.name+"-"+b.id),this.records=a.reject(this.records,function(a){return a==b.id.toString()}),this.save(),b},localStorage:function(){return localStorage}}),b.LocalStorage.sync=window.Store.sync=b.localSync=function(a,b,c,d){var e=b.localStorage||b.collection.localStorage;typeof c=="function"&&(c={success:c,error:d});var f,g=$.Deferred&&$.Deferred();switch(a){case"read":f=b.id!=undefined?e.find(b):e.findAll();break;case"create":f=e.create(b);break;case"update":f=e.update(b);break;case"delete":f=e.destroy(b)}return f?(c.success(f),g&&g.resolve()):(c.error("Record not found"),g&&g.reject()),g&&g.promise()},b.ajaxSync=b.sync,b.getSyncMethod=function(a){return a.localStorage||a.collection&&a.collection.localStorage?b.localSync:b.ajaxSync},b.sync=function(a,c,d,e){return b.getSyncMethod(c).apply(this,[a,c,d,e])}})();

@ -0,0 +1,140 @@
/**
* Backbone localStorage Adapter
* https://github.com/jeromegn/Backbone.localStorage
*/
(function() {
// 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
var _ = this._;
var Backbone = this.Backbone;
// Generate four random hex digits.
function S4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
};
// Generate a pseudo-GUID by concatenating random hexadecimal.
function guid() {
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
};
// 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) {
this.name = name;
var store = this.localStorage().getItem(this.name);
this.records = (store && store.split(",")) || [];
};
_.extend(Backbone.LocalStorage.prototype, {
// Save the current state of the **Store** to *localStorage*.
save: function() {
this.localStorage().setItem(this.name, this.records.join(","));
},
// 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) {
model.id = guid();
model.set(model.idAttribute, model.id);
}
this.localStorage().setItem(this.name+"-"+model.id, JSON.stringify(model));
this.records.push(model.id.toString());
this.save();
return model.toJSON();
},
// 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();
return model.toJSON();
},
// Retrieve a model from `this.data` by id.
find: function(model) {
return JSON.parse(this.localStorage().getItem(this.name+"-"+model.id));
},
// Return the array of all models currently in storage.
findAll: function() {
return _(this.records).chain()
.map(function(id){return JSON.parse(this.localStorage().getItem(this.name+"-"+id));}, this)
.compact()
.value();
},
// Delete a model from `this.data`, returning it.
destroy: function(model) {
this.localStorage().removeItem(this.name+"-"+model.id);
this.records = _.reject(this.records, function(record_id){return record_id == model.id.toString();});
this.save();
return model;
},
localStorage: function() {
return localStorage;
}
});
// localSync delegate to the model or collection's
// *localStorage* property, which should be an instance of `Store`.
// window.Store.sync and Backbone.localSync is deprectated, use Backbone.LocalStorage.sync instead
Backbone.LocalStorage.sync = window.Store.sync = Backbone.localSync = function(method, model, options, error) {
var store = model.localStorage || model.collection.localStorage;
// Backwards compatibility with Backbone <= 0.3.3
if (typeof options == 'function') {
options = {
success: options,
error: error
};
}
var resp, syncDfd = $.Deferred && $.Deferred(); //If $ is having Deferred - use it.
switch (method) {
case "read": resp = model.id != undefined ? store.find(model) : store.findAll(); break;
case "create": resp = store.create(model); break;
case "update": resp = store.update(model); break;
case "delete": resp = store.destroy(model); break;
}
if (resp) {
options.success(resp);
if (syncDfd) syncDfd.resolve();
} else {
options.error("Record not found");
if (syncDfd) syncDfd.reject();
}
return syncDfd && syncDfd.promise();
};
Backbone.ajaxSync = Backbone.sync;
Backbone.getSyncMethod = function(model) {
if(model.localStorage || (model.collection && model.collection.localStorage))
{
return Backbone.localSync;
}
return Backbone.ajaxSync;
};
// Override 'Backbone.sync' to default to localSync,
// the original 'Backbone.sync' is still available in 'Backbone.ajaxSync'
Backbone.sync = function(method, model, options, error) {
return Backbone.getSyncMethod(model).apply(this, [method, model, options, error]);
};
})();

@ -0,0 +1,4 @@
{
"name": "Backbone.localStorage",
"twitter": "jeromegn"
}

@ -0,0 +1,15 @@
{
"author": "Jerome Gravel-Niquet <jeromegn@gmail.com> (http://jgn.me)",
"name": "Backbone.localStorage",
"version": "0.0.0",
"repository": {
"type": "git"
, "url": "git://github.com/jeromegn/Backbone.localStorage.git"
},
"dependencies": {
"uglify-js" : "~1.2.6"
},
"engines": {
"node": "*"
}
}

@ -0,0 +1,32 @@
var fs = require('fs')
, pages = [ new WebPage(), new WebPage() ]
, files = [ fs.absolute('tests/test.html'), fs.absolute('tests/test2.html') ]
, i, page, file;
for (i in pages) {
page = pages[i];
file = files[i];
page.onConsoleMessage = function(msg) {
console.log(msg);
if (msg === "success")
phantom.exit(0);
else
phantom.exit(1);
};
page.onError = function (msg, trace) {
console.log(msg);
trace.forEach(function(item) {
console.log(' ', item.file, ':', item.line);
});
phantom.exit(1);
};
page.open('file://' + file, function (status) {
if (status !== 'success') {
console.log('Failed to load the address');
return phantom.exit(1);
}
});
}

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Backbone Test Suite</title>
<link rel="stylesheet" href="vendor/qunit.css" type="text/css" media="screen" />
<!-- let's wait and see if we need these
<script type="text/javascript" src="vendor/json2.js"></script>
<script type="text/javascript" src="vendor/jquery-1.5.js"></script>
<script type="text/javascript" src="vendor/jslitmus.js"></script>
-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
<script type="text/javascript" src="vendor/qunit.js"></script>
<script type="text/javascript" src="vendor/underscore.js"></script>
<script type="text/javascript" src="vendor/backbone.js"></script>
<script type="text/javascript" src="../backbone.localStorage.js"></script>
<!-- tests -->
<script type="text/javascript" src="test.js"></script>
</head>
<body>
<h1 id="qunit-header">Backbone Test Suite</h1>
<h2 id="qunit-banner"></h2>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<br /><br />
<h1 id="qunit-header"><a href="#">Backbone Speed Suite</a></h1>
<!--
<div id="jslitmus_container" style="margin: 20px 10px;"></div>
-->
</body>
</html>

@ -0,0 +1,207 @@
QUnit.done = function(results){
if (results.failed)
console.log("failed")
else
console.log("success")
};
$(document).ready(function() {
var Library = Backbone.Collection.extend({
localStorage: new Backbone.LocalStorage("libraryStore")
// is the problem with my library that is has no model reference?
});
var attrs = {
title : 'The Tempest',
author : 'Bill Shakespeare',
length : 123
};
var library = null;
module("localStorage on collections", {
setup: function() {
window.localStorage.clear();
library = new Library();
}
});
test("should be empty initially", function() {
equals(library.length, 0, 'empty initially');
library.fetch();
equals(library.length, 0, 'empty read');
});
test("should create item", function() {
library.create(attrs);
equals(library.length, 1, 'one item added');
equals(library.first().get('title'), 'The Tempest', 'title was read');
equals(library.first().get('author'), 'Bill Shakespeare', 'author was read');
equals(library.first().get('length'), 123, 'length was read');
});
test("should discard unsaved changes on fetch", function() {
library.create(attrs);
library.first().set({ 'title': "Wombat's Fun Adventure" });
equals(library.first().get('title'), "Wombat's Fun Adventure", 'title changed, but not saved');
library.fetch();
equals(library.first().get('title'), 'The Tempest', 'title was read');
});
test("should persist changes", function(){
library.create(attrs);
equals(library.first().get('author'), 'Bill Shakespeare', 'author was read');
library.first().save({ author: 'William Shakespeare' });
library.fetch();
equals(library.first().get('author'), 'William Shakespeare', 'verify author update');
});
test("should pass attributes to parse after creating", function() {
var book = new Backbone.Model(attrs);
book.collection = library;
book.parse = function(savedAttrs) {
equal(savedAttrs.title, attrs.title, 'attributes passed to parse')
equal(savedAttrs.author, attrs.author, 'attributes passed to parse')
equal(savedAttrs.length, attrs.length, 'attributes passed to parse')
};
book.save();
});
test("should pass attributes to parse after updating", function() {
var book = library.create(attrs);
book.parse = function(savedAttrs) {
equal(savedAttrs.title, attrs.title, 'attributes passed to parse')
equal(savedAttrs.author, attrs.author, 'attributes passed to parse')
equal(savedAttrs.length, attrs.length, 'attributes passed to parse')
};
book.save();
});
test("should store model id inside collection", function() {
var book = library.create(attrs);
equals(library.get(book.id), book, 'book has been read by id from collection');
});
test("should allow to change id", function() {
library.create(attrs);
library.first().save({id: '1-the-tempest', author: 'William Shakespeare'});
equals(library.first().get('id'), '1-the-tempest', 'verify ID update');
equals(library.first().get('title'), 'The Tempest', 'verify title is still there');
equals(library.first().get('author'), 'William Shakespeare', 'verify author update');
equals(library.first().get('length'), 123, 'verify length is still there');
library.fetch();
equals(library.length, 2, 'should not auto remove first object when changing ID');
});
test("should remove from collection", function() {
_(23).times(function(index) {
library.create({id: index});
});
_(library.toArray()).chain().clone().each(function(book) {
book.destroy();
});
equals(library.length, 0, 'item was destroyed and library is empty');
library.fetch()
equals(library.length, 0, 'item was destroyed and library is empty even after fetch');
});
test("should not try to load items from localstorage if they are not there anymore", function() {
library.create(attrs);
localStorage.clear();
library.fetch();
equals(0, library.length);
});
test("should load from session store without server request", function() {
library.create(attrs);
secondLibrary = new Library();
secondLibrary.fetch();
equals(1, secondLibrary.length);
});
test("should cope with arbitrary idAttributes", function() {
var Model = Backbone.Model.extend({
idAttribute: '_id'
});
var Collection = Backbone.Collection.extend({
model: Model,
localStorage: new Store('strangeID')
});
var collection = new Collection();
collection.create({});
equals(collection.first().id, collection.first().get('_id'));
});
module("localStorage on models", {
setup: function() {
window.localStorage.clear();
book = new Book();
}
});
var Book = Backbone.Model.extend({
defaults: {
title : 'The Tempest',
author : 'Bill Shakespeare',
length : 123
},
localStorage : new Backbone.LocalStorage('TheTempest')
});
var book = null;
test("should overwrite unsaved changes when fetching", function() {
book.save()
book.set({ 'title': "Wombat's Fun Adventure" });
book.fetch();
equals(book.get('title'), 'The Tempest', 'model created');
});
test("should persist changes", function(){
book.save({ author: 'William Shakespeare'});
book.fetch();
equals(book.get('author'), 'William Shakespeare', 'author successfully updated');
equals(book.get('length'), 123, 'verify length is still there');
});
test("should remove book when destroying", function() {
book.save({author: 'fnord'})
equals(Book.prototype.localStorage.findAll().length, 1, 'book removed');
book.destroy()
equals(Book.prototype.localStorage.findAll().length, 0, 'book removed');
});
test("Book should use local sync", function()
{
var method = Backbone.getSyncMethod(book);
equals(method, Backbone.localSync);
});
var MyRemoteModel = Backbone.Model.extend();
var remoteModel = new MyRemoteModel();
test("remoteModel should use ajax sync", function()
{
var method = Backbone.getSyncMethod(remoteModel);
equals(method, Backbone.ajaxSync);
});
test("Backbone.sync should return a value when ajax is used.", function ()
{
var returnValue = remoteModel.fetch({url: '/'});
notEqual(returnValue, undefined);
});
});

@ -0,0 +1,22 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Backbone Test Suite</title>
<link rel="stylesheet" href="vendor/qunit.css" type="text/css" media="screen" />
<script type="text/javascript" src="vendor/qunit.js"></script>
<script type="text/javascript" data-main="test2" src="vendor/require.js"></script>
</head>
<body>
<h1 id="qunit-header">Backbone Test Suite</h1>
<h2 id="qunit-banner"></h2>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
<br /><br />
<h1 id="qunit-header"><a href="#">Backbone Speed Suite</a></h1>
<!--
<div id="jslitmus_container" style="margin: 20px 10px;"></div>
-->
</body>
</html>

@ -0,0 +1,68 @@
define("backbone-loader", [
"vendor/order!vendor/jquery-1.7",
"vendor/order!vendor/underscore",
"vendor/order!vendor/backbone",
"vendor/order!../backbone.localStorage"
], function() {
return { _: _.noConflict(), Backbone: Backbone.noConflict() };
});
define("underscore", ["backbone-loader"], function(Loader) {
return Loader._;
});
define("backbone", ["backbone-loader"], function(Loader) {
return Loader.Backbone;
});
require(["backbone"], function(Backbone) {
var Library = Backbone.Collection.extend({
localStorage: new Backbone.LocalStorage("libraryStore")
});
var attrs = {
title : 'The Tempest',
author : 'Bill Shakespeare',
length : 123
};
var library = null;
module("localStorage on collections", {
setup: function() {
window.localStorage.clear();
library = new Library();
}
});
test("should be empty initially", function() {
equals(library.length, 0, 'empty initially');
library.fetch();
equals(library.length, 0, 'empty read');
});
test("should create item", function() {
library.create(attrs);
equals(library.length, 1, 'one item added');
equals(library.first().get('title'), 'The Tempest', 'title was read');
equals(library.first().get('author'), 'Bill Shakespeare', 'author was read');
equals(library.first().get('length'), 123, 'length was read');
});
test("should discard unsaved changes on fetch", function() {
library.create(attrs);
library.first().set({ 'title': "Wombat's Fun Adventure" });
equals(library.first().get('title'), "Wombat's Fun Adventure", 'title changed, but not saved');
library.fetch();
equals(library.first().get('title'), 'The Tempest', 'title was read');
});
test("should persist changes", function(){
library.create(attrs);
equals(library.first().get('author'), 'Bill Shakespeare', 'author was read');
library.first().save({ author: 'William Shakespeare' });
library.fetch();
equals(library.first().get('author'), 'William Shakespeare', 'verify author update');
});
});

@ -0,0 +1,189 @@
/**
* @license RequireJS order 1.0.5 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license.
* see: http://github.com/jrburke/requirejs for details
*/
/*jslint nomen: false, plusplus: false, strict: false */
/*global require: false, define: false, window: false, document: false,
setTimeout: false */
//Specify that requirejs optimizer should wrap this code in a closure that
//maps the namespaced requirejs API to non-namespaced local variables.
/*requirejs namespace: true */
(function () {
//Sadly necessary browser inference due to differences in the way
//that browsers load and execute dynamically inserted javascript
//and whether the script/cache method works when ordered execution is
//desired. Currently, Gecko and Opera do not load/fire onload for scripts with
//type="script/cache" but they execute injected scripts in order
//unless the 'async' flag is present.
//However, this is all changing in latest browsers implementing HTML5
//spec. With compliant browsers .async true by default, and
//if false, then it will execute in order. Favor that test first for forward
//compatibility.
var testScript = typeof document !== "undefined" &&
typeof window !== "undefined" &&
document.createElement("script"),
supportsInOrderExecution = testScript && (testScript.async ||
((window.opera &&
Object.prototype.toString.call(window.opera) === "[object Opera]") ||
//If Firefox 2 does not have to be supported, then
//a better check may be:
//('mozIsLocallyAvailable' in window.navigator)
("MozAppearance" in document.documentElement.style))),
//This test is true for IE browsers, which will load scripts but only
//execute them once the script is added to the DOM.
supportsLoadSeparateFromExecute = testScript &&
testScript.readyState === 'uninitialized',
readyRegExp = /^(complete|loaded)$/,
cacheWaiting = [],
cached = {},
scriptNodes = {},
scriptWaiting = [];
//Done with the test script.
testScript = null;
//Callback used by the type="script/cache" callback that indicates a script
//has finished downloading.
function scriptCacheCallback(evt) {
var node = evt.currentTarget || evt.srcElement, i,
moduleName, resource;
if (evt.type === "load" || readyRegExp.test(node.readyState)) {
//Pull out the name of the module and the context.
moduleName = node.getAttribute("data-requiremodule");
//Mark this cache request as loaded
cached[moduleName] = true;
//Find out how many ordered modules have loaded
for (i = 0; (resource = cacheWaiting[i]); i++) {
if (cached[resource.name]) {
resource.req([resource.name], resource.onLoad);
} else {
//Something in the ordered list is not loaded,
//so wait.
break;
}
}
//If just loaded some items, remove them from cacheWaiting.
if (i > 0) {
cacheWaiting.splice(0, i);
}
//Remove this script tag from the DOM
//Use a setTimeout for cleanup because some older IE versions vomit
//if removing a script node while it is being evaluated.
setTimeout(function () {
node.parentNode.removeChild(node);
}, 15);
}
}
/**
* Used for the IE case, where fetching is done by creating script element
* but not attaching it to the DOM. This function will be called when that
* happens so it can be determined when the node can be attached to the
* DOM to trigger its execution.
*/
function onFetchOnly(node) {
var i, loadedNode, resourceName;
//Mark this script as loaded.
node.setAttribute('data-orderloaded', 'loaded');
//Cycle through waiting scripts. If the matching node for them
//is loaded, and is in the right order, add it to the DOM
//to execute the script.
for (i = 0; (resourceName = scriptWaiting[i]); i++) {
loadedNode = scriptNodes[resourceName];
if (loadedNode &&
loadedNode.getAttribute('data-orderloaded') === 'loaded') {
delete scriptNodes[resourceName];
require.addScriptToDom(loadedNode);
} else {
break;
}
}
//If just loaded some items, remove them from waiting.
if (i > 0) {
scriptWaiting.splice(0, i);
}
}
define({
version: '1.0.5',
load: function (name, req, onLoad, config) {
var hasToUrl = !!req.nameToUrl,
url, node, context;
//If no nameToUrl, then probably a build with a loader that
//does not support it, and all modules are inlined.
if (!hasToUrl) {
req([name], onLoad);
return;
}
url = req.nameToUrl(name, null);
//Make sure the async attribute is not set for any pathway involving
//this script.
require.s.skipAsync[url] = true;
if (supportsInOrderExecution || config.isBuild) {
//Just a normal script tag append, but without async attribute
//on the script.
req([name], onLoad);
} else if (supportsLoadSeparateFromExecute) {
//Just fetch the URL, but do not execute it yet. The
//non-standards IE case. Really not so nice because it is
//assuming and touching requrejs internals. OK though since
//ordered execution should go away after a long while.
context = require.s.contexts._;
if (!context.urlFetched[url] && !context.loaded[name]) {
//Indicate the script is being fetched.
context.urlFetched[url] = true;
//Stuff from require.load
require.resourcesReady(false);
context.scriptCount += 1;
//Fetch the script now, remember it.
node = require.attach(url, context, name, null, null, onFetchOnly);
scriptNodes[name] = node;
scriptWaiting.push(name);
}
//Do a normal require for it, once it loads, use it as return
//value.
req([name], onLoad);
} else {
//Credit to LABjs author Kyle Simpson for finding that scripts
//with type="script/cache" allow scripts to be downloaded into
//browser cache but not executed. Use that
//so that subsequent addition of a real type="text/javascript"
//tag will cause the scripts to be executed immediately in the
//correct order.
if (req.specified(name)) {
req([name], onLoad);
} else {
cacheWaiting.push({
name: name,
req: req,
onLoad: onLoad
});
require.attach(url, null, name, scriptCacheCallback, "script/cache");
}
}
}
});
}());

@ -0,0 +1,225 @@
/**
* QUnit - A JavaScript Unit Testing Framework
*
* http://docs.jquery.com/QUnit
*
* Copyright (c) 2011 John Resig, Jörn Zaefferer
* Dual licensed under the MIT (MIT-LICENSE.txt)
* or GPL (GPL-LICENSE.txt) licenses.
*/
/** Font Family and Sizes */
#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial, sans-serif;
}
#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
#qunit-tests { font-size: smaller; }
/** Resets */
#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
margin: 0;
padding: 0;
}
/** Header */
#qunit-header {
padding: 0.5em 0 0.5em 1em;
color: #8699a4;
background-color: #0d3349;
font-size: 1.5em;
line-height: 1em;
font-weight: normal;
border-radius: 15px 15px 0 0;
-moz-border-radius: 15px 15px 0 0;
-webkit-border-top-right-radius: 15px;
-webkit-border-top-left-radius: 15px;
}
#qunit-header a {
text-decoration: none;
color: #c2ccd1;
}
#qunit-header a:hover,
#qunit-header a:focus {
color: #fff;
}
#qunit-banner {
height: 5px;
}
#qunit-testrunner-toolbar {
padding: 0.5em 0 0.5em 2em;
color: #5E740B;
background-color: #eee;
}
#qunit-userAgent {
padding: 0.5em 0 0.5em 2.5em;
background-color: #2b81af;
color: #fff;
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
}
/** Tests: Pass/Fail */
#qunit-tests {
list-style-position: inside;
}
#qunit-tests li {
padding: 0.4em 0.5em 0.4em 2.5em;
border-bottom: 1px solid #fff;
list-style-position: inside;
}
#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running {
display: none;
}
#qunit-tests li strong {
cursor: pointer;
}
#qunit-tests li a {
padding: 0.5em;
color: #c2ccd1;
text-decoration: none;
}
#qunit-tests li a:hover,
#qunit-tests li a:focus {
color: #000;
}
#qunit-tests ol {
margin-top: 0.5em;
padding: 0.5em;
background-color: #fff;
border-radius: 15px;
-moz-border-radius: 15px;
-webkit-border-radius: 15px;
box-shadow: inset 0px 2px 13px #999;
-moz-box-shadow: inset 0px 2px 13px #999;
-webkit-box-shadow: inset 0px 2px 13px #999;
}
#qunit-tests table {
border-collapse: collapse;
margin-top: .2em;
}
#qunit-tests th {
text-align: right;
vertical-align: top;
padding: 0 .5em 0 0;
}
#qunit-tests td {
vertical-align: top;
}
#qunit-tests pre {
margin: 0;
white-space: pre-wrap;
word-wrap: break-word;
}
#qunit-tests del {
background-color: #e0f2be;
color: #374e0c;
text-decoration: none;
}
#qunit-tests ins {
background-color: #ffcaca;
color: #500;
text-decoration: none;
}
/*** Test Counts */
#qunit-tests b.counts { color: black; }
#qunit-tests b.passed { color: #5E740B; }
#qunit-tests b.failed { color: #710909; }
#qunit-tests li li {
margin: 0.5em;
padding: 0.4em 0.5em 0.4em 0.5em;
background-color: #fff;
border-bottom: none;
list-style-position: inside;
}
/*** Passing Styles */
#qunit-tests li li.pass {
color: #5E740B;
background-color: #fff;
border-left: 26px solid #C6E746;
}
#qunit-tests .pass { color: #528CE0; background-color: #D2E0E6; }
#qunit-tests .pass .test-name { color: #366097; }
#qunit-tests .pass .test-actual,
#qunit-tests .pass .test-expected { color: #999999; }
#qunit-banner.qunit-pass { background-color: #C6E746; }
/*** Failing Styles */
#qunit-tests li li.fail {
color: #710909;
background-color: #fff;
border-left: 26px solid #EE5757;
}
#qunit-tests > li:last-child {
border-radius: 0 0 15px 15px;
-moz-border-radius: 0 0 15px 15px;
-webkit-border-bottom-right-radius: 15px;
-webkit-border-bottom-left-radius: 15px;
}
#qunit-tests .fail { color: #000000; background-color: #EE5757; }
#qunit-tests .fail .test-name,
#qunit-tests .fail .module-name { color: #000000; }
#qunit-tests .fail .test-actual { color: #EE5757; }
#qunit-tests .fail .test-expected { color: green; }
#qunit-banner.qunit-fail { background-color: #EE5757; }
/** Result */
#qunit-testresult {
padding: 0.5em 0.5em 0.5em 2.5em;
color: #2b81af;
background-color: #D2E0E6;
border-bottom: 1px solid white;
}
/** Fixture */
#qunit-fixture {
position: absolute;
top: -10000px;
left: -10000px;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save