3.0 source code

This commit is contained in:
agolybev
2015-04-28 17:59:00 +03:00
parent c69fd34bdd
commit 7b3b2248e5
16311 changed files with 1445974 additions and 3108429 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,35 @@
(function() {
var sync = Backbone.sync;
var ajax = Backbone.ajax;
var emulateHTTP = Backbone.emulateHTTP;
var emulateJSON = Backbone.emulateJSON;
QUnit.testStart(function() {
var env = this.config.current.testEnvironment;
// Capture ajax settings for comparison.
Backbone.ajax = function(settings) {
env.ajaxSettings = settings;
};
// Capture the arguments to Backbone.sync for comparison.
Backbone.sync = function(method, model, options) {
env.syncArgs = {
method: method,
model: model,
options: options
};
sync.apply(this, arguments);
};
});
QUnit.testDone(function() {
Backbone.sync = sync;
Backbone.ajax = ajax;
Backbone.emulateHTTP = emulateHTTP;
Backbone.emulateJSON = emulateJSON;
});
})();

477
OfficeWeb/vendor/backbone/test/events.js vendored Normal file
View File

@@ -0,0 +1,477 @@
(function() {
module("Backbone.Events");
test("on and trigger", 2, function() {
var obj = { counter: 0 };
_.extend(obj,Backbone.Events);
obj.on('event', function() { obj.counter += 1; });
obj.trigger('event');
equal(obj.counter,1,'counter should be incremented.');
obj.trigger('event');
obj.trigger('event');
obj.trigger('event');
obj.trigger('event');
equal(obj.counter, 5, 'counter should be incremented five times.');
});
test("binding and triggering multiple events", 4, function() {
var obj = { counter: 0 };
_.extend(obj, Backbone.Events);
obj.on('a b c', function() { obj.counter += 1; });
obj.trigger('a');
equal(obj.counter, 1);
obj.trigger('a b');
equal(obj.counter, 3);
obj.trigger('c');
equal(obj.counter, 4);
obj.off('a c');
obj.trigger('a b c');
equal(obj.counter, 5);
});
test("binding and triggering with event maps", function() {
var obj = { counter: 0 };
_.extend(obj, Backbone.Events);
var increment = function() {
this.counter += 1;
};
obj.on({
a: increment,
b: increment,
c: increment
}, obj);
obj.trigger('a');
equal(obj.counter, 1);
obj.trigger('a b');
equal(obj.counter, 3);
obj.trigger('c');
equal(obj.counter, 4);
obj.off({
a: increment,
c: increment
}, obj);
obj.trigger('a b c');
equal(obj.counter, 5);
});
test("listenTo and stopListening", 1, function() {
var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
a.listenTo(b, 'all', function(){ ok(true); });
b.trigger('anything');
a.listenTo(b, 'all', function(){ ok(false); });
a.stopListening();
b.trigger('anything');
});
test("listenTo and stopListening with event maps", 4, function() {
var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
var cb = function(){ ok(true); };
a.listenTo(b, {event: cb});
b.trigger('event');
a.listenTo(b, {event2: cb});
b.on('event2', cb);
a.stopListening(b, {event2: cb});
b.trigger('event event2');
a.stopListening();
b.trigger('event event2');
});
test("stopListening with omitted args", 2, function () {
var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
var cb = function () { ok(true); };
a.listenTo(b, 'event', cb);
b.on('event', cb);
a.listenTo(b, 'event2', cb);
a.stopListening(null, {event: cb});
b.trigger('event event2');
b.off();
a.listenTo(b, 'event event2', cb);
a.stopListening(null, 'event');
a.stopListening();
b.trigger('event2');
});
test("listenToOnce and stopListening", 1, function() {
var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
a.listenToOnce(b, 'all', function() { ok(true); });
b.trigger('anything');
b.trigger('anything');
a.listenToOnce(b, 'all', function() { ok(false); });
a.stopListening();
b.trigger('anything');
});
test("listenTo, listenToOnce and stopListening", 1, function() {
var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
a.listenToOnce(b, 'all', function() { ok(true); });
b.trigger('anything');
b.trigger('anything');
a.listenTo(b, 'all', function() { ok(false); });
a.stopListening();
b.trigger('anything');
});
test("listenTo and stopListening with event maps", 1, function() {
var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
a.listenTo(b, {change: function(){ ok(true); }});
b.trigger('change');
a.listenTo(b, {change: function(){ ok(false); }});
a.stopListening();
b.trigger('change');
});
test("listenTo yourself", 1, function(){
var e = _.extend({}, Backbone.Events);
e.listenTo(e, "foo", function(){ ok(true); });
e.trigger("foo");
});
test("listenTo yourself cleans yourself up with stopListening", 1, function(){
var e = _.extend({}, Backbone.Events);
e.listenTo(e, "foo", function(){ ok(true); });
e.trigger("foo");
e.stopListening();
e.trigger("foo");
});
test("stopListening cleans up references", 4, function() {
var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
var fn = function() {};
a.listenTo(b, 'all', fn).stopListening();
equal(_.size(a._listeningTo), 0);
a.listenTo(b, 'all', fn).stopListening(b);
equal(_.size(a._listeningTo), 0);
a.listenTo(b, 'all', fn).stopListening(null, 'all');
equal(_.size(a._listeningTo), 0);
a.listenTo(b, 'all', fn).stopListening(null, null, fn);
equal(_.size(a._listeningTo), 0);
});
test("listenTo and stopListening cleaning up references", 2, function() {
var a = _.extend({}, Backbone.Events);
var b = _.extend({}, Backbone.Events);
a.listenTo(b, 'all', function(){ ok(true); });
b.trigger('anything');
a.listenTo(b, 'other', function(){ ok(false); });
a.stopListening(b, 'other');
a.stopListening(b, 'all');
equal(_.keys(a._listeningTo).length, 0);
});
test("listenTo with empty callback doesn't throw an error", 1, function(){
var e = _.extend({}, Backbone.Events);
e.listenTo(e, "foo", null);
e.trigger("foo");
ok(true);
});
test("trigger all for each event", 3, function() {
var a, b, obj = { counter: 0 };
_.extend(obj, Backbone.Events);
obj.on('all', function(event) {
obj.counter++;
if (event == 'a') a = true;
if (event == 'b') b = true;
})
.trigger('a b');
ok(a);
ok(b);
equal(obj.counter, 2);
});
test("on, then unbind all functions", 1, function() {
var obj = { counter: 0 };
_.extend(obj,Backbone.Events);
var callback = function() { obj.counter += 1; };
obj.on('event', callback);
obj.trigger('event');
obj.off('event');
obj.trigger('event');
equal(obj.counter, 1, 'counter should have only been incremented once.');
});
test("bind two callbacks, unbind only one", 2, function() {
var obj = { counterA: 0, counterB: 0 };
_.extend(obj,Backbone.Events);
var callback = function() { obj.counterA += 1; };
obj.on('event', callback);
obj.on('event', function() { obj.counterB += 1; });
obj.trigger('event');
obj.off('event', callback);
obj.trigger('event');
equal(obj.counterA, 1, 'counterA should have only been incremented once.');
equal(obj.counterB, 2, 'counterB should have been incremented twice.');
});
test("unbind a callback in the midst of it firing", 1, function() {
var obj = {counter: 0};
_.extend(obj, Backbone.Events);
var callback = function() {
obj.counter += 1;
obj.off('event', callback);
};
obj.on('event', callback);
obj.trigger('event');
obj.trigger('event');
obj.trigger('event');
equal(obj.counter, 1, 'the callback should have been unbound.');
});
test("two binds that unbind themeselves", 2, function() {
var obj = { counterA: 0, counterB: 0 };
_.extend(obj,Backbone.Events);
var incrA = function(){ obj.counterA += 1; obj.off('event', incrA); };
var incrB = function(){ obj.counterB += 1; obj.off('event', incrB); };
obj.on('event', incrA);
obj.on('event', incrB);
obj.trigger('event');
obj.trigger('event');
obj.trigger('event');
equal(obj.counterA, 1, 'counterA should have only been incremented once.');
equal(obj.counterB, 1, 'counterB should have only been incremented once.');
});
test("bind a callback with a supplied context", 1, function () {
var TestClass = function () {
return this;
};
TestClass.prototype.assertTrue = function () {
ok(true, '`this` was bound to the callback');
};
var obj = _.extend({},Backbone.Events);
obj.on('event', function () { this.assertTrue(); }, (new TestClass));
obj.trigger('event');
});
test("nested trigger with unbind", 1, function () {
var obj = { counter: 0 };
_.extend(obj, Backbone.Events);
var incr1 = function(){ obj.counter += 1; obj.off('event', incr1); obj.trigger('event'); };
var incr2 = function(){ obj.counter += 1; };
obj.on('event', incr1);
obj.on('event', incr2);
obj.trigger('event');
equal(obj.counter, 3, 'counter should have been incremented three times');
});
test("callback list is not altered during trigger", 2, function () {
var counter = 0, obj = _.extend({}, Backbone.Events);
var incr = function(){ counter++; };
obj.on('event', function(){ obj.on('event', incr).on('all', incr); })
.trigger('event');
equal(counter, 0, 'bind does not alter callback list');
obj.off()
.on('event', function(){ obj.off('event', incr).off('all', incr); })
.on('event', incr)
.on('all', incr)
.trigger('event');
equal(counter, 2, 'unbind does not alter callback list');
});
test("#1282 - 'all' callback list is retrieved after each event.", 1, function() {
var counter = 0;
var obj = _.extend({}, Backbone.Events);
var incr = function(){ counter++; };
obj.on('x', function() {
obj.on('y', incr).on('all', incr);
})
.trigger('x y');
strictEqual(counter, 2);
});
test("if no callback is provided, `on` is a noop", 0, function() {
_.extend({}, Backbone.Events).on('test').trigger('test');
});
test("if callback is truthy but not a function, `on` should throw an error just like jQuery", 1, function() {
var view = _.extend({}, Backbone.Events).on('test', 'noop');
throws(function() {
view.trigger('test');
});
});
test("remove all events for a specific context", 4, function() {
var obj = _.extend({}, Backbone.Events);
obj.on('x y all', function() { ok(true); });
obj.on('x y all', function() { ok(false); }, obj);
obj.off(null, null, obj);
obj.trigger('x y');
});
test("remove all events for a specific callback", 4, function() {
var obj = _.extend({}, Backbone.Events);
var success = function() { ok(true); };
var fail = function() { ok(false); };
obj.on('x y all', success);
obj.on('x y all', fail);
obj.off(null, fail);
obj.trigger('x y');
});
test("#1310 - off does not skip consecutive events", 0, function() {
var obj = _.extend({}, Backbone.Events);
obj.on('event', function() { ok(false); }, obj);
obj.on('event', function() { ok(false); }, obj);
obj.off(null, null, obj);
obj.trigger('event');
});
test("once", 2, function() {
// Same as the previous test, but we use once rather than having to explicitly unbind
var obj = { counterA: 0, counterB: 0 };
_.extend(obj, Backbone.Events);
var incrA = function(){ obj.counterA += 1; obj.trigger('event'); };
var incrB = function(){ obj.counterB += 1; };
obj.once('event', incrA);
obj.once('event', incrB);
obj.trigger('event');
equal(obj.counterA, 1, 'counterA should have only been incremented once.');
equal(obj.counterB, 1, 'counterB should have only been incremented once.');
});
test("once variant one", 3, function() {
var f = function(){ ok(true); };
var a = _.extend({}, Backbone.Events).once('event', f);
var b = _.extend({}, Backbone.Events).on('event', f);
a.trigger('event');
b.trigger('event');
b.trigger('event');
});
test("once variant two", 3, function() {
var f = function(){ ok(true); };
var obj = _.extend({}, Backbone.Events);
obj
.once('event', f)
.on('event', f)
.trigger('event')
.trigger('event');
});
test("once with off", 0, function() {
var f = function(){ ok(true); };
var obj = _.extend({}, Backbone.Events);
obj.once('event', f);
obj.off('event', f);
obj.trigger('event');
});
test("once with event maps", function() {
var obj = { counter: 0 };
_.extend(obj, Backbone.Events);
var increment = function() {
this.counter += 1;
};
obj.once({
a: increment,
b: increment,
c: increment
}, obj);
obj.trigger('a');
equal(obj.counter, 1);
obj.trigger('a b');
equal(obj.counter, 2);
obj.trigger('c');
equal(obj.counter, 3);
obj.trigger('a b c');
equal(obj.counter, 3);
});
test("once with off only by context", 0, function() {
var context = {};
var obj = _.extend({}, Backbone.Events);
obj.once('event', function(){ ok(false); }, context);
obj.off(null, null, context);
obj.trigger('event');
});
test("Backbone object inherits Events", function() {
ok(Backbone.on === Backbone.Events.on);
});
asyncTest("once with asynchronous events", 1, function() {
var func = _.debounce(function() { ok(true); start(); }, 50);
var obj = _.extend({}, Backbone.Events).once('async', func);
obj.trigger('async');
obj.trigger('async');
});
test("once with multiple events.", 2, function() {
var obj = _.extend({}, Backbone.Events);
obj.once('x y', function() { ok(true); });
obj.trigger('x y');
});
test("Off during iteration with once.", 2, function() {
var obj = _.extend({}, Backbone.Events);
var f = function(){ this.off('event', f); };
obj.on('event', f);
obj.once('event', function(){});
obj.on('event', function(){ ok(true); });
obj.trigger('event');
obj.trigger('event');
});
test("`once` on `all` should work as expected", 1, function() {
Backbone.once('all', function() {
ok(true);
Backbone.trigger('all');
});
Backbone.trigger('all');
});
test("once without a callback is a noop", 0, function() {
_.extend({}, Backbone.Events).once('event').trigger('event');
});
test("event functions are chainable", function() {
var obj = _.extend({}, Backbone.Events);
var obj2 = _.extend({}, Backbone.Events);
var fn = function() {};
equal(obj, obj.trigger('noeventssetyet'));
equal(obj, obj.off('noeventssetyet'));
equal(obj, obj.stopListening('noeventssetyet'));
equal(obj, obj.on('a', fn));
equal(obj, obj.once('c', fn));
equal(obj, obj.trigger('a'));
equal(obj, obj.listenTo(obj2, 'a', fn));
equal(obj, obj.listenToOnce(obj2, 'b', fn));
equal(obj, obj.off('a c'));
equal(obj, obj.stopListening(obj2, 'a'));
equal(obj, obj.stopListening());
});
})();

View File

@@ -0,0 +1,30 @@
<!doctype html>
<html>
<head>
<meta charset='utf8'>
<title>Backbone Test Suite</title>
<link rel="stylesheet" href="vendor/qunit.css" type="text/css" media="screen">
<link rel="icon" href="../docs/images/favicon.ico">
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture">
<div id='testElement'>
<h1>Test</h1>
</div>
</div>
<script src="vendor/json2.js"></script>
<script src="vendor/jquery.js"></script>
<script src="vendor/qunit.js"></script>
<script src="vendor/underscore.js"></script>
<script src="../backbone.js"></script>
<script src="environment.js"></script>
<script src="noconflict.js"></script>
<script src="events.js"></script>
<script src="model.js"></script>
<script src="collection.js"></script>
<script src="router.js"></script>
<script src="view.js"></script>
<script src="sync.js"></script>
</body>
</html>

View File

@@ -0,0 +1,43 @@
# Quick Backbone/CoffeeScript tests to make sure that inheritance
# works correctly.
{ok, equal, deepEqual} = require 'assert'
{Model, Collection, Events} = require '../backbone'
# Patch `ok` to store a count of passed tests...
count = 0
oldOk = ok
ok = ->
oldOk arguments...
count++
class Document extends Model
fullName: ->
@get('name') + ' ' + @get('surname')
tempest = new Document
id : '1-the-tempest',
title : "The Tempest",
name : "William"
surname : "Shakespeare"
length : 123
ok tempest.fullName() is "William Shakespeare"
ok tempest.get('length') is 123
class ProperDocument extends Document
fullName: ->
"Mr. " + super
properTempest = new ProperDocument tempest.attributes
ok properTempest.fullName() is "Mr. William Shakespeare"
ok properTempest.get('length') is 123
console.log "passed #{count} tests"

1110
OfficeWeb/vendor/backbone/test/model.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
(function() {
module("Backbone.noConflict");
test('noConflict', 2, function() {
var noconflictBackbone = Backbone.noConflict();
equal(window.Backbone, undefined, 'Returned window.Backbone');
window.Backbone = noconflictBackbone;
equal(window.Backbone, noconflictBackbone, 'Backbone is still pointing to the original Backbone');
});
})();

729
OfficeWeb/vendor/backbone/test/router.js vendored Normal file
View File

@@ -0,0 +1,729 @@
(function() {
var router = null;
var location = null;
var lastRoute = null;
var lastArgs = [];
function onRoute(router, route, args) {
lastRoute = route;
lastArgs = args;
}
var Location = function(href) {
this.replace(href);
};
_.extend(Location.prototype, {
replace: function(href) {
_.extend(this, _.pick($('<a></a>', {href: href})[0],
'href',
'hash',
'host',
'search',
'fragment',
'pathname',
'protocol'
));
// In IE, anchor.pathname does not contain a leading slash though
// window.location.pathname does.
if (!/^\//.test(this.pathname)) this.pathname = '/' + this.pathname;
},
toString: function() {
return this.href;
}
});
module("Backbone.Router", {
setup: function() {
location = new Location('http://example.com');
Backbone.history = _.extend(new Backbone.History, {location: location});
router = new Router({testing: 101});
Backbone.history.interval = 9;
Backbone.history.start({pushState: false});
lastRoute = null;
lastArgs = [];
Backbone.history.on('route', onRoute);
},
teardown: function() {
Backbone.history.stop();
Backbone.history.off('route', onRoute);
}
});
var ExternalObject = {
value: 'unset',
routingFunction: function(value) {
this.value = value;
}
};
_.bindAll(ExternalObject);
var Router = Backbone.Router.extend({
count: 0,
routes: {
"noCallback": "noCallback",
"counter": "counter",
"search/:query": "search",
"search/:query/p:page": "search",
"charñ": "charUTF",
"char%C3%B1": "charEscaped",
"contacts": "contacts",
"contacts/new": "newContact",
"contacts/:id": "loadContact",
"route-event/:arg": "routeEvent",
"optional(/:item)": "optionalItem",
"named/optional/(y:z)": "namedOptional",
"splat/*args/end": "splat",
":repo/compare/*from...*to": "github",
"decode/:named/*splat": "decode",
"*first/complex-*part/*rest": "complex",
":entity?*args": "query",
"function/:value": ExternalObject.routingFunction,
"*anything": "anything"
},
initialize : function(options) {
this.testing = options.testing;
this.route('implicit', 'implicit');
},
counter: function() {
this.count++;
},
implicit: function() {
this.count++;
},
search: function(query, page) {
this.query = query;
this.page = page;
},
charUTF: function() {
this.charType = 'UTF';
},
charEscaped: function() {
this.charType = 'escaped';
},
contacts: function(){
this.contact = 'index';
},
newContact: function(){
this.contact = 'new';
},
loadContact: function(){
this.contact = 'load';
},
optionalItem: function(arg){
this.arg = arg != void 0 ? arg : null;
},
splat: function(args) {
this.args = args;
},
github: function(repo, from, to) {
this.repo = repo;
this.from = from;
this.to = to;
},
complex: function(first, part, rest) {
this.first = first;
this.part = part;
this.rest = rest;
},
query: function(entity, args) {
this.entity = entity;
this.queryArgs = args;
},
anything: function(whatever) {
this.anything = whatever;
},
namedOptional: function(z) {
this.z = z;
},
decode: function(named, path) {
this.named = named;
this.path = path;
},
routeEvent: function(arg) {
}
});
test("initialize", 1, function() {
equal(router.testing, 101);
});
test("routes (simple)", 4, function() {
location.replace('http://example.com#search/news');
Backbone.history.checkUrl();
equal(router.query, 'news');
equal(router.page, void 0);
equal(lastRoute, 'search');
equal(lastArgs[0], 'news');
});
test("routes (simple, but unicode)", 4, function() {
location.replace('http://example.com#search/тест');
Backbone.history.checkUrl();
equal(router.query, "тест");
equal(router.page, void 0);
equal(lastRoute, 'search');
equal(lastArgs[0], "тест");
});
test("routes (two part)", 2, function() {
location.replace('http://example.com#search/nyc/p10');
Backbone.history.checkUrl();
equal(router.query, 'nyc');
equal(router.page, '10');
});
test("routes via navigate", 2, function() {
Backbone.history.navigate('search/manhattan/p20', {trigger: true});
equal(router.query, 'manhattan');
equal(router.page, '20');
});
test("routes via navigate for backwards-compatibility", 2, function() {
Backbone.history.navigate('search/manhattan/p20', true);
equal(router.query, 'manhattan');
equal(router.page, '20');
});
test("reports matched route via nagivate", 1, function() {
ok(Backbone.history.navigate('search/manhattan/p20', true));
});
test("route precedence via navigate", 6, function(){
// check both 0.9.x and backwards-compatibility options
_.each([ { trigger: true }, true ], function( options ){
Backbone.history.navigate('contacts', options);
equal(router.contact, 'index');
Backbone.history.navigate('contacts/new', options);
equal(router.contact, 'new');
Backbone.history.navigate('contacts/foo', options);
equal(router.contact, 'load');
});
});
test("loadUrl is not called for identical routes.", 0, function() {
Backbone.history.loadUrl = function(){ ok(false); };
location.replace('http://example.com#route');
Backbone.history.navigate('route');
Backbone.history.navigate('/route');
Backbone.history.navigate('/route');
});
test("use implicit callback if none provided", 1, function() {
router.count = 0;
router.navigate('implicit', {trigger: true});
equal(router.count, 1);
});
test("routes via navigate with {replace: true}", 1, function() {
location.replace('http://example.com#start_here');
Backbone.history.checkUrl();
location.replace = function(href) {
strictEqual(href, new Location('http://example.com#end_here').href);
};
Backbone.history.navigate('end_here', {replace: true});
});
test("routes (splats)", 1, function() {
location.replace('http://example.com#splat/long-list/of/splatted_99args/end');
Backbone.history.checkUrl();
equal(router.args, 'long-list/of/splatted_99args');
});
test("routes (github)", 3, function() {
location.replace('http://example.com#backbone/compare/1.0...braddunbar:with/slash');
Backbone.history.checkUrl();
equal(router.repo, 'backbone');
equal(router.from, '1.0');
equal(router.to, 'braddunbar:with/slash');
});
test("routes (optional)", 2, function() {
location.replace('http://example.com#optional');
Backbone.history.checkUrl();
ok(!router.arg);
location.replace('http://example.com#optional/thing');
Backbone.history.checkUrl();
equal(router.arg, 'thing');
});
test("routes (complex)", 3, function() {
location.replace('http://example.com#one/two/three/complex-part/four/five/six/seven');
Backbone.history.checkUrl();
equal(router.first, 'one/two/three');
equal(router.part, 'part');
equal(router.rest, 'four/five/six/seven');
});
test("routes (query)", 5, function() {
location.replace('http://example.com#mandel?a=b&c=d');
Backbone.history.checkUrl();
equal(router.entity, 'mandel');
equal(router.queryArgs, 'a=b&c=d');
equal(lastRoute, 'query');
equal(lastArgs[0], 'mandel');
equal(lastArgs[1], 'a=b&c=d');
});
test("routes (anything)", 1, function() {
location.replace('http://example.com#doesnt-match-a-route');
Backbone.history.checkUrl();
equal(router.anything, 'doesnt-match-a-route');
});
test("routes (function)", 3, function() {
router.on('route', function(name) {
ok(name === '');
});
equal(ExternalObject.value, 'unset');
location.replace('http://example.com#function/set');
Backbone.history.checkUrl();
equal(ExternalObject.value, 'set');
});
test("Decode named parameters, not splats.", 2, function() {
location.replace('http://example.com#decode/a%2Fb/c%2Fd/e');
Backbone.history.checkUrl();
strictEqual(router.named, 'a/b');
strictEqual(router.path, 'c/d/e');
});
test("fires event when router doesn't have callback on it", 1, function() {
router.on("route:noCallback", function(){ ok(true); });
location.replace('http://example.com#noCallback');
Backbone.history.checkUrl();
});
test("#933, #908 - leading slash", 2, function() {
location.replace('http://example.com/root/foo');
Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location});
Backbone.history.start({root: '/root', hashChange: false, silent: true});
strictEqual(Backbone.history.getFragment(), 'foo');
Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {location: location});
Backbone.history.start({root: '/root/', hashChange: false, silent: true});
strictEqual(Backbone.history.getFragment(), 'foo');
});
test("#1003 - History is started before navigate is called", 1, function() {
Backbone.history.stop();
Backbone.history.navigate = function(){ ok(Backbone.History.started); };
Backbone.history.start();
// If this is not an old IE navigate will not be called.
if (!Backbone.history.iframe) ok(true);
});
test("#967 - Route callback gets passed encoded values.", 3, function() {
var route = 'has%2Fslash/complex-has%23hash/has%20space';
Backbone.history.navigate(route, {trigger: true});
strictEqual(router.first, 'has/slash');
strictEqual(router.part, 'has#hash');
strictEqual(router.rest, 'has space');
});
test("correctly handles URLs with % (#868)", 3, function() {
location.replace('http://example.com#search/fat%3A1.5%25');
Backbone.history.checkUrl();
location.replace('http://example.com#search/fat');
Backbone.history.checkUrl();
equal(router.query, 'fat');
equal(router.page, void 0);
equal(lastRoute, 'search');
});
test("#2666 - Hashes with UTF8 in them.", 2, function() {
Backbone.history.navigate('charñ', {trigger: true});
equal(router.charType, 'UTF');
Backbone.history.navigate('char%C3%B1', {trigger: true});
equal(router.charType, 'escaped');
});
test("#1185 - Use pathname when hashChange is not wanted.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/path/name#hash');
Backbone.history = _.extend(new Backbone.History, {location: location});
Backbone.history.start({hashChange: false});
var fragment = Backbone.history.getFragment();
strictEqual(fragment, location.pathname.replace(/^\//, ''));
});
test("#1206 - Strip leading slash before location.assign.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/root/');
Backbone.history = _.extend(new Backbone.History, {location: location});
Backbone.history.start({hashChange: false, root: '/root/'});
location.assign = function(pathname) {
strictEqual(pathname, '/root/fragment');
};
Backbone.history.navigate('/fragment');
});
test("#1387 - Root fragment without trailing slash.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/root');
Backbone.history = _.extend(new Backbone.History, {location: location});
Backbone.history.start({hashChange: false, root: '/root/', silent: true});
strictEqual(Backbone.history.getFragment(), '');
});
test("#1366 - History does not prepend root to fragment.", 2, function() {
Backbone.history.stop();
location.replace('http://example.com/root/');
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(state, title, url) {
strictEqual(url, '/root/x');
}
}
});
Backbone.history.start({
root: '/root/',
pushState: true,
hashChange: false
});
Backbone.history.navigate('x');
strictEqual(Backbone.history.fragment, 'x');
});
test("Normalize root.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/root');
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(state, title, url) {
strictEqual(url, '/root/fragment');
}
}
});
Backbone.history.start({
pushState: true,
root: '/root',
hashChange: false
});
Backbone.history.navigate('fragment');
});
test("Normalize root.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/root#fragment');
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(state, title, url) {},
replaceState: function(state, title, url) {
strictEqual(url, '/root/fragment');
}
}
});
Backbone.history.start({
pushState: true,
root: '/root'
});
});
test("Normalize root.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/root');
Backbone.history = _.extend(new Backbone.History, {location: location});
Backbone.history.loadUrl = function() { ok(true); };
Backbone.history.start({
pushState: true,
root: '/root'
});
});
test("Normalize root - leading slash.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/root');
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(){},
replaceState: function(){}
}
});
Backbone.history.start({root: 'root'});
strictEqual(Backbone.history.root, '/root/');
});
test("Transition from hashChange to pushState.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/root#x/y');
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(){},
replaceState: function(state, title, url){
strictEqual(url, '/root/x/y');
}
}
});
Backbone.history.start({
root: 'root',
pushState: true
});
});
test("#1619: Router: Normalize empty root", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/');
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(){},
replaceState: function(){}
}
});
Backbone.history.start({root: ''});
strictEqual(Backbone.history.root, '/');
});
test("#1619: Router: nagivate with empty root", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/');
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(state, title, url) {
strictEqual(url, '/fragment');
}
}
});
Backbone.history.start({
pushState: true,
root: '',
hashChange: false
});
Backbone.history.navigate('fragment');
});
test("Transition from pushState to hashChange.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/root/x/y?a=b');
location.replace = function(url) {
strictEqual(url, '/root/?a=b#x/y');
};
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: null,
replaceState: null
}
});
Backbone.history.start({
root: 'root',
pushState: true
});
});
test("#1695 - hashChange to pushState with search.", 1, function() {
Backbone.history.stop();
location.replace('http://example.com/root?a=b#x/y');
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(){},
replaceState: function(state, title, url){
strictEqual(url, '/root/x/y?a=b');
}
}
});
Backbone.history.start({
root: 'root',
pushState: true
});
});
test("#1746 - Router allows empty route.", 1, function() {
var Router = Backbone.Router.extend({
routes: {'': 'empty'},
empty: function(){},
route: function(route){
strictEqual(route, '');
}
});
new Router;
});
test("#1794 - Trailing space in fragments.", 1, function() {
var history = new Backbone.History;
strictEqual(history.getFragment('fragment '), 'fragment');
});
test("#1820 - Leading slash and trailing space.", 1, function() {
var history = new Backbone.History;
strictEqual(history.getFragment('/fragment '), 'fragment');
});
test("#1980 - Optional parameters.", 2, function() {
location.replace('http://example.com#named/optional/y');
Backbone.history.checkUrl();
strictEqual(router.z, undefined);
location.replace('http://example.com#named/optional/y123');
Backbone.history.checkUrl();
strictEqual(router.z, '123');
});
test("#2062 - Trigger 'route' event on router instance.", 2, function() {
router.on('route', function(name, args) {
strictEqual(name, 'routeEvent');
deepEqual(args, ['x']);
});
location.replace('http://example.com#route-event/x');
Backbone.history.checkUrl();
});
test("#2255 - Extend routes by making routes a function.", 1, function() {
var RouterBase = Backbone.Router.extend({
routes: function() {
return {
home: "root",
index: "index.html"
};
}
});
var RouterExtended = RouterBase.extend({
routes: function() {
var _super = RouterExtended.__super__.routes;
return _.extend(_super(),
{ show: "show",
search: "search" });
}
});
var router = new RouterExtended();
deepEqual({home: "root", index: "index.html", show: "show", search: "search"}, router.routes);
});
test("#2538 - hashChange to pushState only if both requested.", 0, function() {
Backbone.history.stop();
location.replace('http://example.com/root?a=b#x/y');
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(){},
replaceState: function(){ ok(false); }
}
});
Backbone.history.start({
root: 'root',
pushState: true,
hashChange: false
});
});
test('No hash fallback.', 0, function() {
Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(){},
replaceState: function(){}
}
});
var Router = Backbone.Router.extend({
routes: {
hash: function() { ok(false); }
}
});
var router = new Router;
location.replace('http://example.com/');
Backbone.history.start({
pushState: true,
hashChange: false
});
location.replace('http://example.com/nomatch#hash');
Backbone.history.checkUrl();
});
test('#2656 - No trailing slash on root.', 1, function() {
Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(state, title, url){
strictEqual(url, '/root');
}
}
});
location.replace('http://example.com/root/path');
Backbone.history.start({pushState: true, root: 'root'});
Backbone.history.navigate('');
});
test('#2656 - No trailing slash on root.', 1, function() {
Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(state, title, url) {
strictEqual(url, '/');
}
}
});
location.replace('http://example.com/path');
Backbone.history.start({pushState: true});
Backbone.history.navigate('');
});
test('#2765 - Fragment matching sans query/hash.', 2, function() {
Backbone.history.stop();
Backbone.history = _.extend(new Backbone.History, {
location: location,
history: {
pushState: function(state, title, url) {
strictEqual(url, '/path?query#hash');
}
}
});
var Router = Backbone.Router.extend({
routes: {
path: function() { ok(true); }
}
});
var router = new Router;
location.replace('http://example.com/');
Backbone.history.start({pushState: true});
Backbone.history.navigate('path?query#hash', true);
});
})();

210
OfficeWeb/vendor/backbone/test/sync.js vendored Normal file
View File

@@ -0,0 +1,210 @@
(function() {
var Library = Backbone.Collection.extend({
url : function() { return '/library'; }
});
var library;
var attrs = {
title : "The Tempest",
author : "Bill Shakespeare",
length : 123
};
module("Backbone.sync", {
setup : function() {
library = new Library;
library.create(attrs, {wait: false});
},
teardown: function() {
Backbone.emulateHTTP = false;
}
});
test("read", 4, function() {
library.fetch();
equal(this.ajaxSettings.url, '/library');
equal(this.ajaxSettings.type, 'GET');
equal(this.ajaxSettings.dataType, 'json');
ok(_.isEmpty(this.ajaxSettings.data));
});
test("passing data", 3, function() {
library.fetch({data: {a: 'a', one: 1}});
equal(this.ajaxSettings.url, '/library');
equal(this.ajaxSettings.data.a, 'a');
equal(this.ajaxSettings.data.one, 1);
});
test("create", 6, function() {
equal(this.ajaxSettings.url, '/library');
equal(this.ajaxSettings.type, 'POST');
equal(this.ajaxSettings.dataType, 'json');
var data = JSON.parse(this.ajaxSettings.data);
equal(data.title, 'The Tempest');
equal(data.author, 'Bill Shakespeare');
equal(data.length, 123);
});
test("update", 7, function() {
library.first().save({id: '1-the-tempest', author: 'William Shakespeare'});
equal(this.ajaxSettings.url, '/library/1-the-tempest');
equal(this.ajaxSettings.type, 'PUT');
equal(this.ajaxSettings.dataType, 'json');
var data = JSON.parse(this.ajaxSettings.data);
equal(data.id, '1-the-tempest');
equal(data.title, 'The Tempest');
equal(data.author, 'William Shakespeare');
equal(data.length, 123);
});
test("update with emulateHTTP and emulateJSON", 7, function() {
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
emulateHTTP: true,
emulateJSON: true
});
equal(this.ajaxSettings.url, '/library/2-the-tempest');
equal(this.ajaxSettings.type, 'POST');
equal(this.ajaxSettings.dataType, 'json');
equal(this.ajaxSettings.data._method, 'PUT');
var data = JSON.parse(this.ajaxSettings.data.model);
equal(data.id, '2-the-tempest');
equal(data.author, 'Tim Shakespeare');
equal(data.length, 123);
});
test("update with just emulateHTTP", 6, function() {
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
emulateHTTP: true
});
equal(this.ajaxSettings.url, '/library/2-the-tempest');
equal(this.ajaxSettings.type, 'POST');
equal(this.ajaxSettings.contentType, 'application/json');
var data = JSON.parse(this.ajaxSettings.data);
equal(data.id, '2-the-tempest');
equal(data.author, 'Tim Shakespeare');
equal(data.length, 123);
});
test("update with just emulateJSON", 6, function() {
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'}, {
emulateJSON: true
});
equal(this.ajaxSettings.url, '/library/2-the-tempest');
equal(this.ajaxSettings.type, 'PUT');
equal(this.ajaxSettings.contentType, 'application/x-www-form-urlencoded');
var data = JSON.parse(this.ajaxSettings.data.model);
equal(data.id, '2-the-tempest');
equal(data.author, 'Tim Shakespeare');
equal(data.length, 123);
});
test("read model", 3, function() {
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
library.first().fetch();
equal(this.ajaxSettings.url, '/library/2-the-tempest');
equal(this.ajaxSettings.type, 'GET');
ok(_.isEmpty(this.ajaxSettings.data));
});
test("destroy", 3, function() {
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
library.first().destroy({wait: true});
equal(this.ajaxSettings.url, '/library/2-the-tempest');
equal(this.ajaxSettings.type, 'DELETE');
equal(this.ajaxSettings.data, null);
});
test("destroy with emulateHTTP", 3, function() {
library.first().save({id: '2-the-tempest', author: 'Tim Shakespeare'});
library.first().destroy({
emulateHTTP: true,
emulateJSON: true
});
equal(this.ajaxSettings.url, '/library/2-the-tempest');
equal(this.ajaxSettings.type, 'POST');
equal(JSON.stringify(this.ajaxSettings.data), '{"_method":"DELETE"}');
});
test("urlError", 2, function() {
var model = new Backbone.Model();
raises(function() {
model.fetch();
});
model.fetch({url: '/one/two'});
equal(this.ajaxSettings.url, '/one/two');
});
test("#1052 - `options` is optional.", 0, function() {
var model = new Backbone.Model();
model.url = '/test';
Backbone.sync('create', model);
});
test("Backbone.ajax", 1, function() {
Backbone.ajax = function(settings){
strictEqual(settings.url, '/test');
};
var model = new Backbone.Model();
model.url = '/test';
Backbone.sync('create', model);
});
test("Call provided error callback on error.", 1, function() {
var model = new Backbone.Model;
model.url = '/test';
Backbone.sync('read', model, {
error: function() { ok(true); }
});
this.ajaxSettings.error();
});
test('Use Backbone.emulateHTTP as default.', 2, function() {
var model = new Backbone.Model;
model.url = '/test';
Backbone.emulateHTTP = true;
model.sync('create', model);
strictEqual(this.ajaxSettings.emulateHTTP, true);
Backbone.emulateHTTP = false;
model.sync('create', model);
strictEqual(this.ajaxSettings.emulateHTTP, false);
});
test('Use Backbone.emulateJSON as default.', 2, function() {
var model = new Backbone.Model;
model.url = '/test';
Backbone.emulateJSON = true;
model.sync('create', model);
strictEqual(this.ajaxSettings.emulateJSON, true);
Backbone.emulateJSON = false;
model.sync('create', model);
strictEqual(this.ajaxSettings.emulateJSON, false);
});
test("#1756 - Call user provided beforeSend function.", 4, function() {
Backbone.emulateHTTP = true;
var model = new Backbone.Model;
model.url = '/test';
var xhr = {
setRequestHeader: function(header, value) {
strictEqual(header, 'X-HTTP-Method-Override');
strictEqual(value, 'DELETE');
}
};
model.sync('delete', model, {
beforeSend: function(_xhr) {
ok(_xhr === xhr);
return false;
}
});
strictEqual(this.ajaxSettings.beforeSend(xhr), false);
});
})();

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,481 @@
/*
http://www.JSON.org/json2.js
2009-09-29
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 */
/*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.
if (!this.JSON) {
this.JSON = {};
}
(function () {
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) {
k = rep[i];
if (typeof k === 'string') {
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.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.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.
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 File

@@ -0,0 +1,244 @@
/**
* QUnit v1.12.0 - A JavaScript Unit Testing Framework
*
* http://qunitjs.com
*
* Copyright 2012 jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
*/
/** 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-header, #qunit-banner, #qunit-userAgent, #qunit-testresult, #qunit-modulefilter {
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: 5px 5px 0 0;
-moz-border-radius: 5px 5px 0 0;
-webkit-border-top-right-radius: 5px;
-webkit-border-top-left-radius: 5px;
}
#qunit-header a {
text-decoration: none;
color: #c2ccd1;
}
#qunit-header a:hover,
#qunit-header a:focus {
color: #fff;
}
#qunit-testrunner-toolbar label {
display: inline-block;
padding: 0 .5em 0 .1em;
}
#qunit-banner {
height: 5px;
}
#qunit-testrunner-toolbar {
padding: 0.5em 0 0.5em 2em;
color: #5E740B;
background-color: #eee;
overflow: hidden;
}
#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;
}
#qunit-modulefilter-container {
float: right;
}
/** 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 li .runtime {
float: right;
font-size: smaller;
}
.qunit-assert-list {
margin-top: 0.5em;
padding: 0.5em;
background-color: #fff;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
.qunit-collapsed {
display: none;
}
#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 {
padding: 5px;
background-color: #fff;
border-bottom: none;
list-style-position: inside;
}
/*** Passing Styles */
#qunit-tests li li.pass {
color: #3c510c;
background-color: #fff;
border-left: 10px 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: 10px solid #EE5757;
white-space: pre;
}
#qunit-tests > li:last-child {
border-radius: 0 0 5px 5px;
-moz-border-radius: 0 0 5px 5px;
-webkit-border-bottom-right-radius: 5px;
-webkit-border-bottom-left-radius: 5px;
}
#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;
}
#qunit-testresult .module-name {
font-weight: bold;
}
/** Fixture */
#qunit-fixture {
position: absolute;
top: -10000px;
left: -10000px;
width: 1000px;
height: 1000px;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,127 @@
/*
* QtWebKit-powered headless test runner using PhantomJS
*
* PhantomJS binaries: http://phantomjs.org/download.html
* Requires PhantomJS 1.6+ (1.7+ recommended)
*
* Run with:
* phantomjs runner.js [url-of-your-qunit-testsuite]
*
* e.g.
* phantomjs runner.js http://localhost/qunit/test/index.html
*/
/*jshint latedef:false */
/*global phantom:false, require:false, console:false, window:false, QUnit:false */
(function() {
'use strict';
var args = require('system').args;
// arg[0]: scriptName, args[1...]: arguments
if (args.length !== 2) {
console.error('Usage:\n phantomjs runner.js [url-of-your-qunit-testsuite]');
phantom.exit(1);
}
var url = args[1],
page = require('webpage').create();
// Route `console.log()` calls from within the Page context to the main Phantom context (i.e. current `this`)
page.onConsoleMessage = function(msg) {
console.log(msg);
};
page.onInitialized = function() {
page.evaluate(addLogging);
};
page.onCallback = function(message) {
var result,
failed;
if (message) {
if (message.name === 'QUnit.done') {
result = message.data;
failed = !result || result.failed;
phantom.exit(failed ? 1 : 0);
}
}
};
page.open(url, function(status) {
if (status !== 'success') {
console.error('Unable to access network: ' + status);
phantom.exit(1);
} else {
// Cannot do this verification with the 'DOMContentLoaded' handler because it
// will be too late to attach it if a page does not have any script tags.
var qunitMissing = page.evaluate(function() { return (typeof QUnit === 'undefined' || !QUnit); });
if (qunitMissing) {
console.error('The `QUnit` object is not present on this page.');
phantom.exit(1);
}
// Do nothing... the callback mechanism will handle everything!
}
});
function addLogging() {
window.document.addEventListener('DOMContentLoaded', function() {
var current_test_assertions = [];
QUnit.log(function(details) {
var response;
// Ignore passing assertions
if (details.result) {
return;
}
response = details.message || '';
if (typeof details.expected !== 'undefined') {
if (response) {
response += ', ';
}
response += 'expected: ' + details.expected + ', but was: ' + details.actual;
if (details.source) {
response += "\n" + details.source;
}
}
current_test_assertions.push('Failed assertion: ' + response);
});
QUnit.testDone(function(result) {
var i,
len,
name = result.module + ': ' + result.name;
if (result.failed) {
console.log('Test failed: ' + name);
for (i = 0, len = current_test_assertions.length; i < len; i++) {
console.log(' ' + current_test_assertions[i]);
}
}
current_test_assertions.length = 0;
});
QUnit.done(function(result) {
console.log('Took ' + result.runtime + 'ms to run ' + result.total + ' tests. ' + result.passed + ' passed, ' + result.failed + ' failed.');
if (typeof window.callPhantom === 'function') {
window.callPhantom({
'name': 'QUnit.done',
'data': result
});
}
});
}, false);
}
})();

File diff suppressed because it is too large Load Diff

331
OfficeWeb/vendor/backbone/test/view.js vendored Normal file
View File

@@ -0,0 +1,331 @@
(function() {
var view;
module("Backbone.View", {
setup: function() {
view = new Backbone.View({
id : 'test-view',
className : 'test-view',
other : 'non-special-option'
});
}
});
test("constructor", 3, function() {
equal(view.el.id, 'test-view');
equal(view.el.className, 'test-view');
equal(view.el.other, void 0);
});
test("jQuery", 1, function() {
var view = new Backbone.View;
view.setElement('<p><a><b>test</b></a></p>');
strictEqual(view.$('a b').html(), 'test');
});
test("initialize", 1, function() {
var View = Backbone.View.extend({
initialize: function() {
this.one = 1;
}
});
strictEqual(new View().one, 1);
});
test("delegateEvents", 6, function() {
var counter1 = 0, counter2 = 0;
var view = new Backbone.View({el: '<p><a id="test"></a></p>'});
view.increment = function(){ counter1++; };
view.$el.on('click', function(){ counter2++; });
var events = {'click #test': 'increment'};
view.delegateEvents(events);
view.$('#test').trigger('click');
equal(counter1, 1);
equal(counter2, 1);
view.$('#test').trigger('click');
equal(counter1, 2);
equal(counter2, 2);
view.delegateEvents(events);
view.$('#test').trigger('click');
equal(counter1, 3);
equal(counter2, 3);
});
test("delegateEvents allows functions for callbacks", 3, function() {
var view = new Backbone.View({el: '<p></p>'});
view.counter = 0;
var events = {
click: function() {
this.counter++;
}
};
view.delegateEvents(events);
view.$el.trigger('click');
equal(view.counter, 1);
view.$el.trigger('click');
equal(view.counter, 2);
view.delegateEvents(events);
view.$el.trigger('click');
equal(view.counter, 3);
});
test("delegateEvents ignore undefined methods", 0, function() {
var view = new Backbone.View({el: '<p></p>'});
view.delegateEvents({'click': 'undefinedMethod'});
view.$el.trigger('click');
});
test("undelegateEvents", 6, function() {
var counter1 = 0, counter2 = 0;
var view = new Backbone.View({el: '<p><a id="test"></a></p>'});
view.increment = function(){ counter1++; };
view.$el.on('click', function(){ counter2++; });
var events = {'click #test': 'increment'};
view.delegateEvents(events);
view.$('#test').trigger('click');
equal(counter1, 1);
equal(counter2, 1);
view.undelegateEvents();
view.$('#test').trigger('click');
equal(counter1, 1);
equal(counter2, 2);
view.delegateEvents(events);
view.$('#test').trigger('click');
equal(counter1, 2);
equal(counter2, 3);
});
test("_ensureElement with DOM node el", 1, function() {
var View = Backbone.View.extend({
el: document.body
});
equal(new View().el, document.body);
});
test("_ensureElement with string el", 3, function() {
var View = Backbone.View.extend({
el: "body"
});
strictEqual(new View().el, document.body);
View = Backbone.View.extend({
el: "#testElement > h1"
});
strictEqual(new View().el, $("#testElement > h1").get(0));
View = Backbone.View.extend({
el: "#nonexistent"
});
ok(!new View().el);
});
test("with className and id functions", 2, function() {
var View = Backbone.View.extend({
className: function() {
return 'className';
},
id: function() {
return 'id';
}
});
strictEqual(new View().el.className, 'className');
strictEqual(new View().el.id, 'id');
});
test("with attributes", 2, function() {
var View = Backbone.View.extend({
attributes: {
id: 'id',
'class': 'class'
}
});
strictEqual(new View().el.className, 'class');
strictEqual(new View().el.id, 'id');
});
test("with attributes as a function", 1, function() {
var View = Backbone.View.extend({
attributes: function() {
return {'class': 'dynamic'};
}
});
strictEqual(new View().el.className, 'dynamic');
});
test("multiple views per element", 3, function() {
var count = 0;
var $el = $('<p></p>');
var View = Backbone.View.extend({
el: $el,
events: {
click: function() {
count++;
}
}
});
var view1 = new View;
$el.trigger("click");
equal(1, count);
var view2 = new View;
$el.trigger("click");
equal(3, count);
view1.delegateEvents();
$el.trigger("click");
equal(5, count);
});
test("custom events, with namespaces", 2, function() {
var count = 0;
var View = Backbone.View.extend({
el: $('body'),
events: function() {
return {"fake$event.namespaced": "run"};
},
run: function() {
count++;
}
});
var view = new View;
$('body').trigger('fake$event').trigger('fake$event');
equal(count, 2);
$('body').unbind('.namespaced');
$('body').trigger('fake$event');
equal(count, 2);
});
test("#1048 - setElement uses provided object.", 2, function() {
var $el = $('body');
var view = new Backbone.View({el: $el});
ok(view.$el === $el);
view.setElement($el = $($el));
ok(view.$el === $el);
});
test("#986 - Undelegate before changing element.", 1, function() {
var button1 = $('<button></button>');
var button2 = $('<button></button>');
var View = Backbone.View.extend({
events: {
click: function(e) {
ok(view.el === e.target);
}
}
});
var view = new View({el: button1});
view.setElement(button2);
button1.trigger('click');
button2.trigger('click');
});
test("#1172 - Clone attributes object", 2, function() {
var View = Backbone.View.extend({
attributes: {foo: 'bar'}
});
var view1 = new View({id: 'foo'});
strictEqual(view1.el.id, 'foo');
var view2 = new View();
ok(!view2.el.id);
});
test("#1228 - tagName can be provided as a function", 1, function() {
var View = Backbone.View.extend({
tagName: function() {
return 'p';
}
});
ok(new View().$el.is('p'));
});
test("views stopListening", 0, function() {
var View = Backbone.View.extend({
initialize: function() {
this.listenTo(this.model, 'all x', function(){ ok(false); }, this);
this.listenTo(this.collection, 'all x', function(){ ok(false); }, this);
}
});
var view = new View({
model: new Backbone.Model,
collection: new Backbone.Collection
});
view.stopListening();
view.model.trigger('x');
view.collection.trigger('x');
});
test("Provide function for el.", 2, function() {
var View = Backbone.View.extend({
el: function() {
return "<p><a></a></p>";
}
});
var view = new View;
ok(view.$el.is('p'));
ok(view.$el.has('a'));
});
test("events passed in options", 2, function() {
var counter = 0;
var View = Backbone.View.extend({
el: '<p><a id="test"></a></p>',
increment: function() {
counter++;
}
});
var view = new View({events:{'click #test':'increment'}});
var view2 = new View({events:function(){
return {'click #test':'increment'};
}});
view.$('#test').trigger('click');
view2.$('#test').trigger('click');
equal(counter, 2);
view.$('#test').trigger('click');
view2.$('#test').trigger('click');
equal(counter, 4);
});
})();