Commit 28e16092 authored by Pascal Hartig's avatar Pascal Hartig

flight: upgrade libraries

Upgraded to flight 1.0.4 which removed `Component#bind` in favor of the native
or polyfilled `Function#bind` and used the new require.js bower format.

Waiting for @phuu to upgrade to Flight 1.1. :)
parent 49d9a24f
...@@ -6,7 +6,7 @@ require.config({ ...@@ -6,7 +6,7 @@ require.config({
jquery: 'bower_components/jquery/jquery', jquery: 'bower_components/jquery/jquery',
es5shim: 'bower_components/es5-shim/es5-shim', es5shim: 'bower_components/es5-shim/es5-shim',
es5sham: 'bower_components/es5-shim/es5-sham', es5sham: 'bower_components/es5-shim/es5-sham',
text: 'bower_components/requirejs/plugins/text' text: 'bower_components/requirejs-text/text'
}, },
map: { map: {
'*': { '*': {
......
...@@ -93,8 +93,8 @@ define([ ...@@ -93,8 +93,8 @@ define([
this.on('click', { 'toggleSelector': this.toggle }); this.on('click', { 'toggleSelector': this.toggle });
this.on('dblclick', { 'labelSelector': this.edit }); this.on('dblclick', { 'labelSelector': this.edit });
this.$node.on('blur', '.edit', this.bind(this.requestUpdate)); this.$node.on('blur', '.edit', this.requestUpdate.bind(this));
this.$node.on('keydown', '.edit', this.bind(this.requestUpdateOnEnter)); this.$node.on('keydown', '.edit', this.requestUpdateOnEnter.bind(this));
// these don't work // these don't work
// this.on(this.attr.editSelector, 'blur', this.requestUpdate); // this.on(this.attr.editSelector, 'blur', this.requestUpdate);
......
...@@ -4,9 +4,10 @@ ...@@ -4,9 +4,10 @@
"dependencies": { "dependencies": {
"depot": "~0.1.4", "depot": "~0.1.4",
"es5-shim": "git://github.com/kriskowal/es5-shim.git#2.0.0", "es5-shim": "git://github.com/kriskowal/es5-shim.git#2.0.0",
"flight": "~1.0.3", "flight": "~1.0.4",
"jquery": "1.8.3", "jquery": "1.8.3",
"requirejs": "~2.1.5", "requirejs": "~2.1.5",
"todomvc-common": "~0.1.4" "todomvc-common": "~0.1.4",
"requirejs-text": "~2.0.10"
} }
} }
/* ---------------------------------- // depot.js v0.1.6
* depot.js v0.1.0
* Licensed under The MIT License // (c) 2013 Michal Kuklis
* http://opensource.org/licenses/MIT // Licensed under The MIT License
* ---------------------------------- */ // http://opensource.org/licenses/MIT
// commonjs, amd, global
(function (name, root, factory) { (function (name, root, factory) {
if (typeof exports === 'object') { if (typeof exports == 'object') {
module.exports = factory(); module.exports = factory();
} else if (typeof define === 'function' && define.amd) { } else if (typeof define == 'function' && define.amd) {
define(factory); define(factory);
} else { } else {
root[name] = factory(); root[name] = factory();
} }
}("depot", this, function () { }("depot", this, function () {
"use strict"; "use strict";
// depot api // depot api
...@@ -28,17 +27,30 @@ ...@@ -28,17 +27,30 @@
record[this.idAttribute] = guid(); record[this.idAttribute] = guid();
} }
id = record[this.idAttribute]; id = record[this.idAttribute] + '';
if (this.ids.indexOf(id) >= 0) { if (this.ids.indexOf(id) < 0) {
record = extend(this.get(id), record);
}
else {
this.ids.push(id); this.ids.push(id);
localStorage.setItem(this.name, this.ids.join(",")); this.storageAdaptor.setItem(this.name, this.ids.join(","));
} }
localStorage.setItem(getKey(this.name, id), JSON.stringify(record)); this.storageAdaptor.setItem(getKey(this.name, id), JSON.stringify(record));
return record;
},
update: function (id, data) {
if (typeof data == 'undefined') {
data = id;
id = data[this.idAttribute];
}
var record = this.get(id);
if (record) {
record = extend(record, data);
this.save(record);
}
return record; return record;
}, },
...@@ -57,11 +69,12 @@ ...@@ -57,11 +69,12 @@
find: function (criteria) { find: function (criteria) {
var key, match, record; var key, match, record;
var name = this.name; var name = this.name;
var self = this;
if (!criteria) return this.all(); if (!criteria) return this.all();
return this.ids.reduce(function (memo, id) { return this.ids.reduce(function (memo, id) {
record = jsonData(localStorage.getItem(getKey(name, id))); record = jsonData(self.storageAdaptor.getItem(getKey(name, id)));
match = findMatch(criteria, record); match = findMatch(criteria, record);
if (match) { if (match) {
...@@ -73,14 +86,14 @@ ...@@ -73,14 +86,14 @@
}, },
get: function (id) { get: function (id) {
return jsonData(localStorage.getItem(getKey(this.name, id))); return jsonData(this.storageAdaptor.getItem(getKey(this.name, id)));
}, },
all: function () { all: function () {
var record, name = this.name; var record, self = this, name = this.name;
return this.ids.reduce(function (memo, id) { return this.ids.reduce(function (memo, id) {
record = localStorage.getItem(getKey(name, id)); record = self.storageAdaptor.getItem(getKey(name, id));
if (record) { if (record) {
memo.push(jsonData(record)); memo.push(jsonData(record));
...@@ -95,12 +108,12 @@ ...@@ -95,12 +108,12 @@
var id = (record[this.idAttribute]) ? record[this.idAttribute] : record; var id = (record[this.idAttribute]) ? record[this.idAttribute] : record;
var key = getKey(this.name, id); var key = getKey(this.name, id);
record = jsonData(localStorage.getItem(key)); record = jsonData(this.storageAdaptor.getItem(key));
localStorage.removeItem(key); this.storageAdaptor.removeItem(key);
index = this.ids.indexOf(id); index = this.ids.indexOf(id);
if (index != -1) this.ids.splice(index, 1); if (index != -1) this.ids.splice(index, 1);
localStorage.setItem(this.name, this.ids.join(",")); this.storageAdaptor.setItem(this.name, this.ids.join(","));
return record; return record;
}, },
...@@ -114,27 +127,31 @@ ...@@ -114,27 +127,31 @@
if (criteria) { if (criteria) {
record = jsonData(localStorage.getItem(key)); record = jsonData(this.storageAdaptor.getItem(key));
match = findMatch(criteria, record); match = findMatch(criteria, record);
if (match) { if (match) {
localStorage.removeItem(key); this.storageAdaptor.removeItem(key);
this.ids.splice(i, 1); this.ids.splice(i, 1);
} }
} }
else { else {
localStorage.removeItem(key); this.storageAdaptor.removeItem(key);
} }
} }
if (criteria) { if (criteria) {
localStorage.setItem(this.name, this.ids.join(",")); this.storageAdaptor.setItem(this.name, this.ids.join(","));
} }
else { else {
localStorage.removeItem(this.name); this.storageAdaptor.removeItem(this.name);
this.ids = []; this.ids = [];
} }
},
size: function () {
return this.ids.length;
} }
}; };
...@@ -170,7 +187,7 @@ ...@@ -170,7 +187,7 @@
} }
function guid() { function guid() {
return s4() + s4() + '-' + s4() + '-' + s4() + return s4() + s4() + '-' + s4() + '-' + s4() +
'-' +s4() + '-' + s4() + s4() + s4(); '-' +s4() + '-' + s4() + s4() + s4();
} }
...@@ -187,17 +204,22 @@ ...@@ -187,17 +204,22 @@
function depot(name, options) { function depot(name, options) {
var store, ids; var store, ids;
if (!localStorage) throw new Error("localStorage not found"); options = extend({
idAttribute: '_id',
storageAdaptor: localStorage
}, options);
if (!options.storageAdaptor) throw new Error("No storage adaptor was found");
store = localStorage.getItem(name); store = options.storageAdaptor.getItem(name);
ids = (store && store.split(",")) || []; ids = (store && store.split(",")) || [];
options = options || {};
return Object.create(api, { return Object.create(api, {
name: { value: name }, name: { value: name },
store: { value: store }, store: { value: store },
ids: { value: ids, writable: true }, ids: { value: ids, writable: true },
idAttribute: { value: options.idAttribute || '_id' } idAttribute: { value: options.idAttribute },
storageAdaptor: { value: options.storageAdaptor }
}); });
} }
......
// Copyright 2009-2012 by contributors, MIT License // Copyright 2009-2012 by contributors, MIT License
// vim: ts=4 sts=4 sw=4 expandtab // vim: ts=4 sts=4 sw=4 expandtab
// Module systems magic dance // Module systems magic dance
(function (definition) { (function (definition) {
// RequireJS // RequireJS
...@@ -95,63 +96,15 @@ if (!Object.getOwnPropertyNames) { ...@@ -95,63 +96,15 @@ if (!Object.getOwnPropertyNames) {
// ES5 15.2.3.5 // ES5 15.2.3.5
// http://es5.github.com/#x15.2.3.5 // http://es5.github.com/#x15.2.3.5
if (!Object.create) { if (!Object.create) {
// Contributed by Brandon Benvie, October, 2012
var createEmpty;
var supportsProto = Object.prototype.__proto__ === null;
if (supportsProto || typeof document == 'undefined') {
createEmpty = function () {
return { "__proto__": null };
};
} else {
// In old IE __proto__ can't be used to manually set `null`, nor does
// any other method exist to make an object that inherits from nothing,
// aside from Object.prototype itself. Instead, create a new global
// object and *steal* its Object.prototype and strip it bare. This is
// used as the prototype to create nullary objects.
createEmpty = (function () {
var iframe = document.createElement('iframe');
var parent = document.body || document.documentElement;
iframe.style.display = 'none';
parent.appendChild(iframe);
iframe.src = 'javascript:';
var empty = iframe.contentWindow.Object.prototype;
parent.removeChild(iframe);
iframe = null;
delete empty.constructor;
delete empty.hasOwnProperty;
delete empty.propertyIsEnumerable;
delete empty.isPrototypeOf;
delete empty.toLocaleString;
delete empty.toString;
delete empty.valueOf;
empty.__proto__ = null;
function Empty() {}
Empty.prototype = empty;
return function () {
return new Empty();
};
})();
}
Object.create = function create(prototype, properties) { Object.create = function create(prototype, properties) {
var object; var object;
function Type() {} // An empty constructor.
if (prototype === null) { if (prototype === null) {
object = createEmpty(); object = { "__proto__": null };
} else { } else {
if (typeof prototype !== "object" && typeof prototype !== "function") { if (typeof prototype != "object") {
// In the native implementation `parent` can be `null` throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'");
// OR *any* `instanceof Object` (Object|Function|Array|RegExp|etc)
// Use `typeof` tho, b/c in old IE, DOM elements are not `instanceof Object`
// like they are in modern browsers. Using `Object.create` on DOM elements
// is...err...probably inappropriate, but the native version allows for it.
throw new TypeError("Object prototype may only be an Object or null"); // same msg as Chrome
} }
var Type = function () {};
Type.prototype = prototype; Type.prototype = prototype;
object = new Type(); object = new Type();
// IE has no built-in implementation of `Object.getPrototypeOf` // IE has no built-in implementation of `Object.getPrototypeOf`
...@@ -160,11 +113,9 @@ if (!Object.create) { ...@@ -160,11 +113,9 @@ if (!Object.create) {
// objects created using `Object.create` // objects created using `Object.create`
object.__proto__ = prototype; object.__proto__ = prototype;
} }
if (properties !== void 0) { if (properties !== void 0) {
Object.defineProperties(object, properties); Object.defineProperties(object, properties);
} }
return object; return object;
}; };
} }
...@@ -197,8 +148,7 @@ if (Object.defineProperty) { ...@@ -197,8 +148,7 @@ if (Object.defineProperty) {
var definePropertyWorksOnDom = typeof document == "undefined" || var definePropertyWorksOnDom = typeof document == "undefined" ||
doesDefinePropertyWork(document.createElement("div")); doesDefinePropertyWork(document.createElement("div"));
if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) { if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) {
var definePropertyFallback = Object.defineProperty, var definePropertyFallback = Object.defineProperty;
definePropertiesFallback = Object.defineProperties;
} }
} }
...@@ -278,17 +228,8 @@ if (!Object.defineProperty || definePropertyFallback) { ...@@ -278,17 +228,8 @@ if (!Object.defineProperty || definePropertyFallback) {
// ES5 15.2.3.7 // ES5 15.2.3.7
// http://es5.github.com/#x15.2.3.7 // http://es5.github.com/#x15.2.3.7
if (!Object.defineProperties || definePropertiesFallback) { if (!Object.defineProperties) {
Object.defineProperties = function defineProperties(object, properties) { Object.defineProperties = function defineProperties(object, properties) {
// make a valiant attempt to use the real defineProperties
if (definePropertiesFallback) {
try {
return definePropertiesFallback.call(Object, object, properties);
} catch (exception) {
// try the shim if the real one doesn't work
}
}
for (var property in properties) { for (var property in properties) {
if (owns(properties, property) && property != "__proto__") { if (owns(properties, property) && property != "__proto__") {
Object.defineProperty(object, property, properties[property]); Object.defineProperty(object, property, properties[property]);
......
...@@ -32,8 +32,6 @@ ...@@ -32,8 +32,6 @@
// ES-5 15.3.4.5 // ES-5 15.3.4.5
// http://es5.github.com/#x15.3.4.5 // http://es5.github.com/#x15.3.4.5
function Empty() {}
if (!Function.prototype.bind) { if (!Function.prototype.bind) {
Function.prototype.bind = function bind(that) { // .length is 1 Function.prototype.bind = function bind(that) { // .length is 1
// 1. Let Target be the this value. // 1. Let Target be the this value.
...@@ -74,14 +72,18 @@ if (!Function.prototype.bind) { ...@@ -74,14 +72,18 @@ if (!Function.prototype.bind) {
// 5. Return the result of calling the [[Construct]] internal // 5. Return the result of calling the [[Construct]] internal
// method of target providing args as the arguments. // method of target providing args as the arguments.
var F = function(){};
F.prototype = target.prototype;
var self = new F;
var result = target.apply( var result = target.apply(
this, self,
args.concat(slice.call(arguments)) args.concat(slice.call(arguments))
); );
if (Object(result) === result) { if (Object(result) === result) {
return result; return result;
} }
return this; return self;
} else { } else {
// 15.3.4.5.1 [[Call]] // 15.3.4.5.1 [[Call]]
...@@ -111,12 +113,6 @@ if (!Function.prototype.bind) { ...@@ -111,12 +113,6 @@ if (!Function.prototype.bind) {
} }
}; };
if(target.prototype) {
Empty.prototype = target.prototype;
bound.prototype = new Empty();
// Clean up dangling references.
Empty.prototype = null;
}
// XXX bound.length is never writable, so don't even try // XXX bound.length is never writable, so don't even try
// //
// 15. If the [[Class]] internal property of Target is "Function", then // 15. If the [[Class]] internal property of Target is "Function", then
...@@ -182,38 +178,6 @@ if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) { ...@@ -182,38 +178,6 @@ if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) {
// ===== // =====
// //
// ES5 15.4.4.12
// http://es5.github.com/#x15.4.4.12
// Default value for second param
// [bugfix, ielt9, old browsers]
// IE < 9 bug: [1,2].splice(0).join("") == "" but should be "12"
if ([1,2].splice(0).length != 2) {
var array_splice = Array.prototype.splice;
Array.prototype.splice = function(start, deleteCount) {
if (!arguments.length) {
return [];
} else {
return array_splice.apply(this, [
start === void 0 ? 0 : start,
deleteCount === void 0 ? (this.length - start) : deleteCount
].concat(slice.call(arguments, 2)))
}
};
}
// ES5 15.4.4.12
// http://es5.github.com/#x15.4.4.13
// Return len+argCount.
// [bugfix, ielt8]
// IE < 8 bug: [].unshift(0) == undefined but should be "1"
if ([].unshift(0) != 1) {
var array_unshift = Array.prototype.unshift;
Array.prototype.unshift = function() {
array_unshift.apply(this, arguments);
return this.length;
};
}
// ES5 15.4.3.2 // ES5 15.4.3.2
// http://es5.github.com/#x15.4.3.2 // http://es5.github.com/#x15.4.3.2
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray
...@@ -238,18 +202,9 @@ if (!Array.isArray) { ...@@ -238,18 +202,9 @@ if (!Array.isArray) {
// ES5 15.4.4.18 // ES5 15.4.4.18
// http://es5.github.com/#x15.4.4.18 // http://es5.github.com/#x15.4.4.18
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach
// Check failure of by-index access of string characters (IE < 9)
// and failure of `0 in boxedString` (Rhino)
var boxedString = Object("a"),
splitString = boxedString[0] != "a" || !(0 in boxedString);
if (!Array.prototype.forEach) { if (!Array.prototype.forEach) {
Array.prototype.forEach = function forEach(fun /*, thisp*/) { Array.prototype.forEach = function forEach(fun /*, thisp*/) {
var object = toObject(this), var self = toObject(this),
self = splitString && _toString(this) == "[object String]" ?
this.split("") :
object,
thisp = arguments[1], thisp = arguments[1],
i = -1, i = -1,
length = self.length >>> 0; length = self.length >>> 0;
...@@ -262,9 +217,8 @@ if (!Array.prototype.forEach) { ...@@ -262,9 +217,8 @@ if (!Array.prototype.forEach) {
while (++i < length) { while (++i < length) {
if (i in self) { if (i in self) {
// Invoke the callback function with call, passing arguments: // Invoke the callback function with call, passing arguments:
// context, property value, property key, thisArg object // context, property value, property key, thisArg object context
// context fun.call(thisp, self[i], i, self);
fun.call(thisp, self[i], i, object);
} }
} }
}; };
...@@ -275,10 +229,7 @@ if (!Array.prototype.forEach) { ...@@ -275,10 +229,7 @@ if (!Array.prototype.forEach) {
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map
if (!Array.prototype.map) { if (!Array.prototype.map) {
Array.prototype.map = function map(fun /*, thisp*/) { Array.prototype.map = function map(fun /*, thisp*/) {
var object = toObject(this), var self = toObject(this),
self = splitString && _toString(this) == "[object String]" ?
this.split("") :
object,
length = self.length >>> 0, length = self.length >>> 0,
result = Array(length), result = Array(length),
thisp = arguments[1]; thisp = arguments[1];
...@@ -290,7 +241,7 @@ if (!Array.prototype.map) { ...@@ -290,7 +241,7 @@ if (!Array.prototype.map) {
for (var i = 0; i < length; i++) { for (var i = 0; i < length; i++) {
if (i in self) if (i in self)
result[i] = fun.call(thisp, self[i], i, object); result[i] = fun.call(thisp, self[i], i, self);
} }
return result; return result;
}; };
...@@ -301,10 +252,7 @@ if (!Array.prototype.map) { ...@@ -301,10 +252,7 @@ if (!Array.prototype.map) {
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter
if (!Array.prototype.filter) { if (!Array.prototype.filter) {
Array.prototype.filter = function filter(fun /*, thisp */) { Array.prototype.filter = function filter(fun /*, thisp */) {
var object = toObject(this), var self = toObject(this),
self = splitString && _toString(this) == "[object String]" ?
this.split("") :
object,
length = self.length >>> 0, length = self.length >>> 0,
result = [], result = [],
value, value,
...@@ -318,7 +266,7 @@ if (!Array.prototype.filter) { ...@@ -318,7 +266,7 @@ if (!Array.prototype.filter) {
for (var i = 0; i < length; i++) { for (var i = 0; i < length; i++) {
if (i in self) { if (i in self) {
value = self[i]; value = self[i];
if (fun.call(thisp, value, i, object)) { if (fun.call(thisp, value, i, self)) {
result.push(value); result.push(value);
} }
} }
...@@ -332,10 +280,7 @@ if (!Array.prototype.filter) { ...@@ -332,10 +280,7 @@ if (!Array.prototype.filter) {
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every
if (!Array.prototype.every) { if (!Array.prototype.every) {
Array.prototype.every = function every(fun /*, thisp */) { Array.prototype.every = function every(fun /*, thisp */) {
var object = toObject(this), var self = toObject(this),
self = splitString && _toString(this) == "[object String]" ?
this.split("") :
object,
length = self.length >>> 0, length = self.length >>> 0,
thisp = arguments[1]; thisp = arguments[1];
...@@ -345,7 +290,7 @@ if (!Array.prototype.every) { ...@@ -345,7 +290,7 @@ if (!Array.prototype.every) {
} }
for (var i = 0; i < length; i++) { for (var i = 0; i < length; i++) {
if (i in self && !fun.call(thisp, self[i], i, object)) { if (i in self && !fun.call(thisp, self[i], i, self)) {
return false; return false;
} }
} }
...@@ -358,10 +303,7 @@ if (!Array.prototype.every) { ...@@ -358,10 +303,7 @@ if (!Array.prototype.every) {
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some
if (!Array.prototype.some) { if (!Array.prototype.some) {
Array.prototype.some = function some(fun /*, thisp */) { Array.prototype.some = function some(fun /*, thisp */) {
var object = toObject(this), var self = toObject(this),
self = splitString && _toString(this) == "[object String]" ?
this.split("") :
object,
length = self.length >>> 0, length = self.length >>> 0,
thisp = arguments[1]; thisp = arguments[1];
...@@ -371,7 +313,7 @@ if (!Array.prototype.some) { ...@@ -371,7 +313,7 @@ if (!Array.prototype.some) {
} }
for (var i = 0; i < length; i++) { for (var i = 0; i < length; i++) {
if (i in self && fun.call(thisp, self[i], i, object)) { if (i in self && fun.call(thisp, self[i], i, self)) {
return true; return true;
} }
} }
...@@ -384,10 +326,7 @@ if (!Array.prototype.some) { ...@@ -384,10 +326,7 @@ if (!Array.prototype.some) {
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce
if (!Array.prototype.reduce) { if (!Array.prototype.reduce) {
Array.prototype.reduce = function reduce(fun /*, initial*/) { Array.prototype.reduce = function reduce(fun /*, initial*/) {
var object = toObject(this), var self = toObject(this),
self = splitString && _toString(this) == "[object String]" ?
this.split("") :
object,
length = self.length >>> 0; length = self.length >>> 0;
// If no callback function or if callback is not a callable function // If no callback function or if callback is not a callable function
...@@ -397,7 +336,7 @@ if (!Array.prototype.reduce) { ...@@ -397,7 +336,7 @@ if (!Array.prototype.reduce) {
// no value to return if no initial value and an empty array // no value to return if no initial value and an empty array
if (!length && arguments.length == 1) { if (!length && arguments.length == 1) {
throw new TypeError("reduce of empty array with no initial value"); throw new TypeError('reduce of empty array with no initial value');
} }
var i = 0; var i = 0;
...@@ -413,14 +352,14 @@ if (!Array.prototype.reduce) { ...@@ -413,14 +352,14 @@ if (!Array.prototype.reduce) {
// if array contains no values, no initial value to return // if array contains no values, no initial value to return
if (++i >= length) { if (++i >= length) {
throw new TypeError("reduce of empty array with no initial value"); throw new TypeError('reduce of empty array with no initial value');
} }
} while (true); } while (true);
} }
for (; i < length; i++) { for (; i < length; i++) {
if (i in self) { if (i in self) {
result = fun.call(void 0, result, self[i], i, object); result = fun.call(void 0, result, self[i], i, self);
} }
} }
...@@ -433,10 +372,7 @@ if (!Array.prototype.reduce) { ...@@ -433,10 +372,7 @@ if (!Array.prototype.reduce) {
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight
if (!Array.prototype.reduceRight) { if (!Array.prototype.reduceRight) {
Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) { Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) {
var object = toObject(this), var self = toObject(this),
self = splitString && _toString(this) == "[object String]" ?
this.split("") :
object,
length = self.length >>> 0; length = self.length >>> 0;
// If no callback function or if callback is not a callable function // If no callback function or if callback is not a callable function
...@@ -446,7 +382,7 @@ if (!Array.prototype.reduceRight) { ...@@ -446,7 +382,7 @@ if (!Array.prototype.reduceRight) {
// no value to return if no initial value, empty array // no value to return if no initial value, empty array
if (!length && arguments.length == 1) { if (!length && arguments.length == 1) {
throw new TypeError("reduceRight of empty array with no initial value"); throw new TypeError('reduceRight of empty array with no initial value');
} }
var result, i = length - 1; var result, i = length - 1;
...@@ -461,14 +397,14 @@ if (!Array.prototype.reduceRight) { ...@@ -461,14 +397,14 @@ if (!Array.prototype.reduceRight) {
// if array contains no values, no initial value to return // if array contains no values, no initial value to return
if (--i < 0) { if (--i < 0) {
throw new TypeError("reduceRight of empty array with no initial value"); throw new TypeError('reduceRight of empty array with no initial value');
} }
} while (true); } while (true);
} }
do { do {
if (i in this) { if (i in this) {
result = fun.call(void 0, result, self[i], i, object); result = fun.call(void 0, result, self[i], i, self);
} }
} while (i--); } while (i--);
...@@ -479,11 +415,9 @@ if (!Array.prototype.reduceRight) { ...@@ -479,11 +415,9 @@ if (!Array.prototype.reduceRight) {
// ES5 15.4.4.14 // ES5 15.4.4.14
// http://es5.github.com/#x15.4.4.14 // http://es5.github.com/#x15.4.4.14
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf
if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) { if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) { Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) {
var self = splitString && _toString(this) == "[object String]" ? var self = toObject(this),
this.split("") :
toObject(this),
length = self.length >>> 0; length = self.length >>> 0;
if (!length) { if (!length) {
...@@ -509,11 +443,9 @@ if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) { ...@@ -509,11 +443,9 @@ if (!Array.prototype.indexOf || ([0, 1].indexOf(1, 2) != -1)) {
// ES5 15.4.4.15 // ES5 15.4.4.15
// http://es5.github.com/#x15.4.4.15 // http://es5.github.com/#x15.4.4.15
// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf
if (!Array.prototype.lastIndexOf || ([0, 1].lastIndexOf(0, -3) != -1)) { if (!Array.prototype.lastIndexOf) {
Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) { Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) {
var self = splitString && _toString(this) == "[object String]" ? var self = toObject(this),
this.split("") :
toObject(this),
length = self.length >>> 0; length = self.length >>> 0;
if (!length) { if (!length) {
...@@ -561,10 +493,7 @@ if (!Object.keys) { ...@@ -561,10 +493,7 @@ if (!Object.keys) {
Object.keys = function keys(object) { Object.keys = function keys(object) {
if ( if ((typeof object != "object" && typeof object != "function") || object === null) {
(typeof object != "object" && typeof object != "function") ||
object === null
) {
throw new TypeError("Object.keys called on a non-object"); throw new TypeError("Object.keys called on a non-object");
} }
...@@ -600,96 +529,64 @@ if (!Object.keys) { ...@@ -600,96 +529,64 @@ if (!Object.keys) {
// string format defined in 15.9.1.15. All fields are present in the String. // string format defined in 15.9.1.15. All fields are present in the String.
// The time zone is always UTC, denoted by the suffix Z. If the time value of // The time zone is always UTC, denoted by the suffix Z. If the time value of
// this object is not a finite Number a RangeError exception is thrown. // this object is not a finite Number a RangeError exception is thrown.
var negativeDate = -62198755200000, if (!Date.prototype.toISOString || (new Date(-62198755200000).toISOString().indexOf('-000001') === -1)) {
negativeYearString = "-000001";
if (
!Date.prototype.toISOString ||
(new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1)
) {
Date.prototype.toISOString = function toISOString() { Date.prototype.toISOString = function toISOString() {
var result, length, value, year, month; var result, length, value, year;
if (!isFinite(this)) { if (!isFinite(this)) {
throw new RangeError("Date.prototype.toISOString called on non-finite value."); throw new RangeError("Date.prototype.toISOString called on non-finite value.");
} }
year = this.getUTCFullYear();
month = this.getUTCMonth();
// see https://github.com/kriskowal/es5-shim/issues/111
year += Math.floor(month / 12);
month = (month % 12 + 12) % 12;
// the date time string format is specified in 15.9.1.15. // the date time string format is specified in 15.9.1.15.
result = [month + 1, this.getUTCDate(), result = [this.getUTCMonth() + 1, this.getUTCDate(),
this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()]; this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()];
year = ( year = this.getUTCFullYear();
(year < 0 ? "-" : (year > 9999 ? "+" : "")) + year = (year < 0 ? '-' : (year > 9999 ? '+' : '')) + ('00000' + Math.abs(year)).slice(0 <= year && year <= 9999 ? -4 : -6);
("00000" + Math.abs(year))
.slice(0 <= year && year <= 9999 ? -4 : -6)
);
length = result.length; length = result.length;
while (length--) { while (length--) {
value = result[length]; value = result[length];
// pad months, days, hours, minutes, and seconds to have two // pad months, days, hours, minutes, and seconds to have two digits.
// digits.
if (value < 10) { if (value < 10) {
result[length] = "0" + value; result[length] = "0" + value;
} }
} }
// pad milliseconds to have three digits. // pad milliseconds to have three digits.
return ( return year + "-" + result.slice(0, 2).join("-") + "T" + result.slice(2).join(":") + "." +
year + "-" + result.slice(0, 2).join("-") + ("000" + this.getUTCMilliseconds()).slice(-3) + "Z";
"T" + result.slice(2).join(":") + "." + }
("000" + this.getUTCMilliseconds()).slice(-3) + "Z"
);
};
} }
// ES5 15.9.4.4
// http://es5.github.com/#x15.9.4.4
if (!Date.now) {
Date.now = function now() {
return new Date().getTime();
};
}
// ES5 15.9.5.44 // ES5 15.9.5.44
// http://es5.github.com/#x15.9.5.44 // http://es5.github.com/#x15.9.5.44
// This function provides a String representation of a Date object for use by // This function provides a String representation of a Date object for use by
// JSON.stringify (15.12.3). // JSON.stringify (15.12.3).
var dateToJSONIsSupported = false; if (!Date.prototype.toJSON) {
try {
dateToJSONIsSupported = (
Date.prototype.toJSON &&
new Date(NaN).toJSON() === null &&
new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 &&
Date.prototype.toJSON.call({ // generic
toISOString: function () {
return true;
}
})
);
} catch (e) {
}
if (!dateToJSONIsSupported) {
Date.prototype.toJSON = function toJSON(key) { Date.prototype.toJSON = function toJSON(key) {
// When the toJSON method is called with argument key, the following // When the toJSON method is called with argument key, the following
// steps are taken: // steps are taken:
// 1. Let O be the result of calling ToObject, giving it the this // 1. Let O be the result of calling ToObject, giving it the this
// value as its argument. // value as its argument.
// 2. Let tv be toPrimitive(O, hint Number). // 2. Let tv be ToPrimitive(O, hint Number).
var o = Object(this),
tv = toPrimitive(o),
toISO;
// 3. If tv is a Number and is not finite, return null. // 3. If tv is a Number and is not finite, return null.
if (typeof tv === "number" && !isFinite(tv)) { // XXX
return null;
}
// 4. Let toISO be the result of calling the [[Get]] internal method of // 4. Let toISO be the result of calling the [[Get]] internal method of
// O with argument "toISOString". // O with argument "toISOString".
toISO = o.toISOString;
// 5. If IsCallable(toISO) is false, throw a TypeError exception. // 5. If IsCallable(toISO) is false, throw a TypeError exception.
if (typeof toISO != "function") { if (typeof this.toISOString != "function") {
throw new TypeError("toISOString property is not callable"); throw new TypeError('toISOString property is not callable');
} }
// 6. Return the result of calling the [[Call]] internal method of // 6. Return the result of calling the [[Call]] internal method of
// toISO with O as the this value and an empty argument list. // toISO with O as the this value and an empty argument list.
return toISO.call(o); return this.toISOString();
// NOTE 1 The argument is ignored. // NOTE 1 The argument is ignored.
...@@ -706,13 +603,13 @@ if (!dateToJSONIsSupported) { ...@@ -706,13 +603,13 @@ if (!dateToJSONIsSupported) {
// http://es5.github.com/#x15.9.4.2 // http://es5.github.com/#x15.9.4.2
// based on work shared by Daniel Friesen (dantman) // based on work shared by Daniel Friesen (dantman)
// http://gist.github.com/303249 // http://gist.github.com/303249
if (!Date.parse || "Date.parse is buggy") { if (!Date.parse || Date.parse("+275760-09-13T00:00:00.000Z") !== 8.64e15) {
// XXX global assignment won't work in embeddings that use // XXX global assignment won't work in embeddings that use
// an alternate object for the context. // an alternate object for the context.
Date = (function(NativeDate) { Date = (function(NativeDate) {
// Date.length === 7 // Date.length === 7
function Date(Y, M, D, h, m, s, ms) { var Date = function Date(Y, M, D, h, m, s, ms) {
var length = arguments.length; var length = arguments.length;
if (this instanceof NativeDate) { if (this instanceof NativeDate) {
var date = length == 1 && String(Y) === Y ? // isString(Y) var date = length == 1 && String(Y) === Y ? // isString(Y)
...@@ -737,8 +634,7 @@ if (!Date.parse || "Date.parse is buggy") { ...@@ -737,8 +634,7 @@ if (!Date.parse || "Date.parse is buggy") {
// 15.9.1.15 Date Time String Format. // 15.9.1.15 Date Time String Format.
var isoDateExpression = new RegExp("^" + var isoDateExpression = new RegExp("^" +
"(\\d{4}|[\+\-]\\d{6})" + // four-digit year capture or sign + "(\\d{4}|[\+\-]\\d{6})" + // four-digit year capture or sign + 6-digit extended year
// 6-digit extended year
"(?:-(\\d{2})" + // optional month capture "(?:-(\\d{2})" + // optional month capture
"(?:-(\\d{2})" + // optional day capture "(?:-(\\d{2})" + // optional day capture
"(?:" + // capture hours:minutes:seconds.milliseconds "(?:" + // capture hours:minutes:seconds.milliseconds
...@@ -748,7 +644,7 @@ if (!Date.parse || "Date.parse is buggy") { ...@@ -748,7 +644,7 @@ if (!Date.parse || "Date.parse is buggy") {
":(\\d{2})" + // seconds capture ":(\\d{2})" + // seconds capture
"(?:\\.(\\d{3}))?" + // milliseconds capture "(?:\\.(\\d{3}))?" + // milliseconds capture
")?" + ")?" +
"(" + // capture UTC offset component "(?:" + // capture UTC offset component
"Z|" + // UTC capture "Z|" + // UTC capture
"(?:" + // offset specifier +/-hours:minutes "(?:" + // offset specifier +/-hours:minutes
"([-+])" + // sign capture "([-+])" + // sign capture
...@@ -758,21 +654,6 @@ if (!Date.parse || "Date.parse is buggy") { ...@@ -758,21 +654,6 @@ if (!Date.parse || "Date.parse is buggy") {
")?)?)?)?" + ")?)?)?)?" +
"$"); "$");
var months = [
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
];
function dayFromMonth(year, month) {
var t = month > 1 ? 1 : 0;
return (
months[month] +
Math.floor((year - 1969 + t) / 4) -
Math.floor((year - 1901 + t) / 100) +
Math.floor((year - 1601 + t) / 400) +
365 * (year - 1970)
);
}
// Copy any custom methods a 3rd party library may have added // Copy any custom methods a 3rd party library may have added
for (var key in NativeDate) { for (var key in NativeDate) {
Date[key] = NativeDate[key]; Date[key] = NativeDate[key];
...@@ -788,53 +669,47 @@ if (!Date.parse || "Date.parse is buggy") { ...@@ -788,53 +669,47 @@ if (!Date.parse || "Date.parse is buggy") {
Date.parse = function parse(string) { Date.parse = function parse(string) {
var match = isoDateExpression.exec(string); var match = isoDateExpression.exec(string);
if (match) { if (match) {
match.shift(); // kill match[0], the full match
// parse months, days, hours, minutes, seconds, and milliseconds // parse months, days, hours, minutes, seconds, and milliseconds
// provide default values if necessary for (var i = 1; i < 7; i++) {
// provide default values if necessary
match[i] = +(match[i] || (i < 3 ? 1 : 0));
// match[1] is the month. Months are 0-11 in JavaScript
// `Date` objects, but 1-12 in ISO notation, so we
// decrement.
if (i == 1) {
match[i]--;
}
}
// parse the UTC offset component // parse the UTC offset component
var year = Number(match[1]), var minuteOffset = +match.pop(), hourOffset = +match.pop(), sign = match.pop();
month = Number(match[2] || 1) - 1,
day = Number(match[3] || 1) - 1, // compute the explicit time zone offset if specified
hour = Number(match[4] || 0), var offset = 0;
minute = Number(match[5] || 0), if (sign) {
second = Number(match[6] || 0), // detect invalid offsets and return early
millisecond = Number(match[7] || 0), if (hourOffset > 23 || minuteOffset > 59) {
// When time zone is missed, local offset should be used return NaN;
// (ES 5.1 bug)
// see https://bugs.ecmascript.org/show_bug.cgi?id=112
offset = !match[4] || match[8] ?
0 : Number(new NativeDate(1970, 0)),
signOffset = match[9] === "-" ? 1 : -1,
hourOffset = Number(match[10] || 0),
minuteOffset = Number(match[11] || 0),
result;
if (
hour < (
minute > 0 || second > 0 || millisecond > 0 ?
24 : 25
) &&
minute < 60 && second < 60 && millisecond < 1000 &&
month > -1 && month < 12 && hourOffset < 24 &&
minuteOffset < 60 && // detect invalid offsets
day > -1 &&
day < (
dayFromMonth(year, month + 1) -
dayFromMonth(year, month)
)
) {
result = (
(dayFromMonth(year, month) + day) * 24 +
hour +
hourOffset * signOffset
) * 60;
result = (
(result + minute + minuteOffset * signOffset) * 60 +
second
) * 1000 + millisecond + offset;
if (-8.64e15 <= result && result <= 8.64e15) {
return result;
} }
// express the provided time zone offset in minutes. The offset is
// negative for time zones west of UTC; positive otherwise.
offset = (hourOffset * 60 + minuteOffset) * 6e4 * (sign == "+" ? -1 : 1);
} }
return NaN;
// Date.UTC for years between 0 and 99 converts year to 1900 + year
// The Gregorian calendar has a 400-year cycle, so
// to Date.UTC(year + 400, .... ) - 12622780800000 == Date.UTC(year, ...),
// where 12622780800000 - number of milliseconds in Gregorian calendar 400 years
var year = +match[0];
if (0 <= year && year <= 99) {
match[0] = year + 400;
return NativeDate.UTC.apply(this, match) + offset - 12622780800000;
}
// compute a new UTC date value, accounting for the optional offset
return NativeDate.UTC.apply(this, match) + offset;
} }
return NativeDate.parse.apply(this, arguments); return NativeDate.parse.apply(this, arguments);
}; };
...@@ -843,59 +718,11 @@ if (!Date.parse || "Date.parse is buggy") { ...@@ -843,59 +718,11 @@ if (!Date.parse || "Date.parse is buggy") {
})(Date); })(Date);
} }
// ES5 15.9.4.4
// http://es5.github.com/#x15.9.4.4
if (!Date.now) {
Date.now = function now() {
return new Date().getTime();
};
}
// //
// String // String
// ====== // ======
// //
// ES5 15.5.4.14
// http://es5.github.com/#x15.5.4.14
// [bugfix, chrome]
// If separator is undefined, then the result array contains just one String,
// which is the this value (converted to a String). If limit is not undefined,
// then the output array is truncated so that it contains no more than limit
// elements.
// "0".split(undefined, 0) -> []
if("0".split(void 0, 0).length) {
var string_split = String.prototype.split;
String.prototype.split = function(separator, limit) {
if(separator === void 0 && limit === 0)return [];
return string_split.apply(this, arguments);
}
}
// ECMA-262, 3rd B.2.3
// Note an ECMAScript standart, although ECMAScript 3rd Edition has a
// non-normative section suggesting uniform semantics and it should be
// normalized across all browsers
// [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE
if("".substr && "0b".substr(-1) !== "b") {
var string_substr = String.prototype.substr;
/**
* Get the substring of a string
* @param {integer} start where to start the substring
* @param {integer} length how many characters to return
* @return {string}
*/
String.prototype.substr = function(start, length) {
return string_substr.call(
this,
start < 0 ? ((start = this.length + start) < 0 ? 0 : start) : start,
length
);
}
}
// ES5 15.5.4.20 // ES5 15.5.4.20
// http://es5.github.com/#x15.5.4.20 // http://es5.github.com/#x15.5.4.20
var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" + var ws = "\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003" +
...@@ -911,9 +738,7 @@ if (!String.prototype.trim || ws.trim()) { ...@@ -911,9 +738,7 @@ if (!String.prototype.trim || ws.trim()) {
if (this === undefined || this === null) { if (this === undefined || this === null) {
throw new TypeError("can't convert "+this+" to object"); throw new TypeError("can't convert "+this+" to object");
} }
return String(this) return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, "");
.replace(trimBeginRegexp, "")
.replace(trimEndRegexp, "");
}; };
} }
...@@ -925,8 +750,7 @@ if (!String.prototype.trim || ws.trim()) { ...@@ -925,8 +750,7 @@ if (!String.prototype.trim || ws.trim()) {
// ES5 9.4 // ES5 9.4
// http://es5.github.com/#x9.4 // http://es5.github.com/#x9.4
// http://jsperf.com/to-integer // http://jsperf.com/to-integer
var toInteger = function (n) {
function toInteger(n) {
n = +n; n = +n;
if (n !== n) { // isNaN if (n !== n) { // isNaN
n = 0; n = 0;
...@@ -934,47 +758,20 @@ function toInteger(n) { ...@@ -934,47 +758,20 @@ function toInteger(n) {
n = (n > 0 || -1) * Math.floor(Math.abs(n)); n = (n > 0 || -1) * Math.floor(Math.abs(n));
} }
return n; return n;
} };
function isPrimitive(input) {
var type = typeof input;
return (
input === null ||
type === "undefined" ||
type === "boolean" ||
type === "number" ||
type === "string"
);
}
function toPrimitive(input) {
var val, valueOf, toString;
if (isPrimitive(input)) {
return input;
}
valueOf = input.valueOf;
if (typeof valueOf === "function") {
val = valueOf.call(input);
if (isPrimitive(val)) {
return val;
}
}
toString = input.toString;
if (typeof toString === "function") {
val = toString.call(input);
if (isPrimitive(val)) {
return val;
}
}
throw new TypeError();
}
// ES5 9.9 var prepareString = "a"[0] != "a";
// http://es5.github.com/#x9.9 // ES5 9.9
// http://es5.github.com/#x9.9
var toObject = function (o) { var toObject = function (o) {
if (o == null) { // this matches both null and undefined if (o == null) { // this matches both null and undefined
throw new TypeError("can't convert "+o+" to object"); throw new TypeError("can't convert "+o+" to object");
} }
// If the implementation doesn't support by-index access of
// string characters (ex. IE < 9), split the string
if (prepareString && typeof o == "string" && o) {
return o.split("");
}
return Object(o); return Object(o);
}; };
......
...@@ -18,37 +18,31 @@ define( ...@@ -18,37 +18,31 @@ define(
var advice = { var advice = {
around: function(base, wrapped) { around: function(base, wrapped) {
return function() { return function composedAround() {
var args = util.toArray(arguments); // unpacking arguments by hand benchmarked faster
return wrapped.apply(this, [base.bind(this)].concat(args)); var i = 0, l = arguments.length, args = new Array(l + 1);
args[0] = base.bind(this);
for (; i < l; i++) args[i + 1] = arguments[i];
return wrapped.apply(this, args);
} }
}, },
before: function(base, before) { before: function(base, before) {
return this.around(base, function() { var beforeFn = (typeof before == 'function') ? before : before.obj[before.fnName];
var args = util.toArray(arguments), return function composedBefore() {
orig = args.shift(), beforeFn.apply(this, arguments);
beforeFn; return base.apply(this, arguments);
}
beforeFn = (typeof before == 'function') ? before : before.obj[before.fnName];
beforeFn.apply(this, args);
return (orig).apply(this, args);
});
}, },
after: function(base, after) { after: function(base, after) {
return this.around(base, function() { var afterFn = (typeof after == 'function') ? after : after.obj[after.fnName];
var args = util.toArray(arguments), return function composedAfter() {
orig = args.shift(), var res = (base.unbound || base).apply(this, arguments);
afterFn; afterFn.apply(this, arguments);
// this is a separate statement for debugging purposes.
var res = (orig.unbound || orig).apply(this, args);
afterFn = (typeof after == 'function') ? after : after.obj[after.fnName];
afterFn.apply(this, args);
return res; return res;
}); }
}, },
// a mixin that allows other mixins to augment existing functions by adding additional // a mixin that allows other mixins to augment existing functions by adding additional
......
...@@ -12,13 +12,15 @@ define( ...@@ -12,13 +12,15 @@ define(
'./advice', './advice',
'./utils', './utils',
'./compose', './compose',
'./registry' './registry',
'./logger',
'../tools/debug/debug'
], ],
function(advice, utils, compose, registry) { function(advice, utils, compose, registry, withLogging, debug) {
var functionNameRegEx = /function (.*?)\s?\(/; var functionNameRegEx = /function (.*?)\s?\(/;
var spaceCommaRegEx = /\s\,/g; var componentId = 0;
function teardownInstance(instanceInfo){ function teardownInstance(instanceInfo){
instanceInfo.events.slice().forEach(function(event) { instanceInfo.events.slice().forEach(function(event) {
...@@ -33,7 +35,6 @@ define( ...@@ -33,7 +35,6 @@ define(
function teardown() { function teardown() {
this.trigger("componentTearDown");
teardownInstance(registry.findInstanceInfo(this)); teardownInstance(registry.findInstanceInfo(this));
} }
...@@ -41,11 +42,23 @@ define( ...@@ -41,11 +42,23 @@ define(
function teardownAll() { function teardownAll() {
var componentInfo = registry.findComponentInfo(this); var componentInfo = registry.findComponentInfo(this);
componentInfo && componentInfo.instances.slice().forEach(function(info) { componentInfo && Object.keys(componentInfo.instances).forEach(function(k) {
var info = componentInfo.instances[k];
info.instance.teardown(); info.instance.teardown();
}); });
} }
function checkSerializable(type, data) {
try {
window.postMessage(data, '*');
} catch(e) {
console.log('unserializable data for event',type,':',data);
throw new Error(
["The event", type, "on component", this.toString(), "was triggered with non-serializable data"].join(" ")
);
}
}
//common mixin allocates basic functionality - used by all component prototypes //common mixin allocates basic functionality - used by all component prototypes
//callback context is bound to component //callback context is bound to component
function withBaseComponent() { function withBaseComponent() {
...@@ -53,50 +66,70 @@ define( ...@@ -53,50 +66,70 @@ define(
// delegate trigger, bind and unbind to an element // delegate trigger, bind and unbind to an element
// if $element not supplied, use component's node // if $element not supplied, use component's node
// other arguments are passed on // other arguments are passed on
// event can be either a string specifying the type
// of the event, or a hash specifying both the type
// and a default function to be called.
this.trigger = function() { this.trigger = function() {
var $element, type, data; var $element, type, data, event, defaultFn;
var args = utils.toArray(arguments); var lastIndex = arguments.length - 1, lastArg = arguments[lastIndex];
if (typeof args[args.length - 1] != "string") { if (typeof lastArg != "string" && !(lastArg && lastArg.defaultBehavior)) {
data = args.pop(); lastIndex--;
data = lastArg;
} }
$element = (args.length == 2) ? $(args.shift()) : this.$node; if (lastIndex == 1) {
type = args[0]; $element = $(arguments[0]);
event = arguments[1];
if (window.DEBUG && window.postMessage) { } else {
try { $element = this.$node;
window.postMessage(data, '*'); event = arguments[0];
} catch(e) { }
console.log('unserializable data for event',type,':',data);
throw new Error( if (event.defaultBehavior) {
["The event", event.type, "on component", this.describe, "was triggered with non-serializable data"].join(" ") defaultFn = event.defaultBehavior;
); event = $.Event(event.type);
} }
type = event.type || event;
if (debug.enabled && window.postMessage) {
checkSerializable.call(this, type, data);
} }
if (typeof this.attr.eventData === 'object') { if (typeof this.attr.eventData === 'object') {
data = $.extend(true, {}, this.attr.eventData, data); data = $.extend(true, {}, this.attr.eventData, data);
} }
return $element.trigger(type, data); $element.trigger((event || type), data);
if (defaultFn && !event.isDefaultPrevented()) {
(this[defaultFn] || defaultFn).call(this);
}
return $element;
}; };
this.on = function() { this.on = function() {
var $element, type, callback, originalCb; var $element, type, callback, originalCb;
var args = utils.toArray(arguments); var lastIndex = arguments.length - 1, origin = arguments[lastIndex];
if (typeof args[args.length - 1] == "object") { if (typeof origin == "object") {
//delegate callback //delegate callback
originalCb = utils.delegate( originalCb = utils.delegate(
this.resolveDelegateRules(args.pop()) this.resolveDelegateRules(origin)
); );
} else { } else {
originalCb = args.pop(); originalCb = origin;
} }
$element = (args.length == 2) ? $(args.shift()) : this.$node; if (lastIndex == 2) {
type = args[0]; $element = $(arguments[0]);
type = arguments[1];
} else {
$element = this.$node;
type = arguments[0];
}
if (typeof originalCb != 'function' && typeof originalCb != 'object') { if (typeof originalCb != 'function' && typeof originalCb != 'object') {
throw new Error("Unable to bind to '" + type + "' because the given callback is not a function or an object"); throw new Error("Unable to bind to '" + type + "' because the given callback is not a function or an object");
...@@ -120,14 +153,20 @@ define( ...@@ -120,14 +153,20 @@ define(
this.off = function() { this.off = function() {
var $element, type, callback; var $element, type, callback;
var args = utils.toArray(arguments); var lastIndex = arguments.length - 1;
if (typeof args[args.length - 1] == "function") { if (typeof arguments[lastIndex] == "function") {
callback = args.pop(); callback = arguments[lastIndex];
lastIndex -= 1;
} }
$element = (args.length == 2) ? $(args.shift()) : this.$node; if (lastIndex == 1) {
type = args[0]; $element = $(arguments[0]);
type = arguments[1];
} else {
$element = this.$node;
type = arguments[0];
}
return $element.off(type, callback); return $element.off(type, callback);
}; };
...@@ -135,15 +174,12 @@ define( ...@@ -135,15 +174,12 @@ define(
this.resolveDelegateRules = function(ruleInfo) { this.resolveDelegateRules = function(ruleInfo) {
var rules = {}; var rules = {};
Object.keys(ruleInfo).forEach( Object.keys(ruleInfo).forEach(function(r) {
function(r) { if (!r in this.attr) {
if (!this.attr.hasOwnProperty(r)) { throw new Error('Component "' + this.toString() + '" wants to listen on "' + r + '" but no such attribute was defined.');
throw new Error('Component "' + this.describe + '" wants to listen on "' + r + '" but no such attribute was defined.'); }
} rules[this.attr[r]] = ruleInfo[r];
rules[this.attr[r]] = ruleInfo[r]; }, this);
},
this
);
return rules; return rules;
}; };
...@@ -161,13 +197,25 @@ define( ...@@ -161,13 +197,25 @@ define(
} }
function attachTo(selector/*, options args */) { function attachTo(selector/*, options args */) {
// unpacking arguments by hand benchmarked faster
var l = arguments.length;
var args = new Array(l - 1);
for (var i = 1; i < l; i++) args[i - 1] = arguments[i];
if (!selector) { if (!selector) {
throw new Error("Component needs to be attachTo'd a jQuery object, native node or selector string"); throw new Error("Component needs to be attachTo'd a jQuery object, native node or selector string");
} }
var options = utils.merge.apply(utils, utils.toArray(arguments, 1)); var options = utils.merge.apply(utils, args);
$(selector).each(function(i, node) { $(selector).each(function(i, node) {
var rawNode = node.jQuery ? node[0] : node;
var componentInfo = registry.findComponentInfo(this)
if (componentInfo && componentInfo.isAttachedTo(rawNode)) {
//already attached
return;
}
new this(node, options); new this(node, options);
}.bind(this)); }.bind(this));
} }
...@@ -176,26 +224,32 @@ define( ...@@ -176,26 +224,32 @@ define(
// takes an unlimited number of mixin functions as arguments // takes an unlimited number of mixin functions as arguments
// typical api call with 3 mixins: define(timeline, withTweetCapability, withScrollCapability); // typical api call with 3 mixins: define(timeline, withTweetCapability, withScrollCapability);
function define(/*mixins*/) { function define(/*mixins*/) {
var mixins = utils.toArray(arguments); // unpacking arguments by hand benchmarked faster
var l = arguments.length;
var mixins = new Array(l + 3); //add three for common mixins
for (var i = 0; i < l; i++) mixins[i] = arguments[i];
Component.toString = function() { Component.toString = function() {
var prettyPrintMixins = mixins.map(function(mixin) { var prettyPrintMixins = mixins.map(function(mixin) {
if ($.browser.msie) { if (mixin.name == null) {
//function name property not supported by this browser, use regex
var m = mixin.toString().match(functionNameRegEx); var m = mixin.toString().match(functionNameRegEx);
return (m && m[1]) ? m[1] : ""; return (m && m[1]) ? m[1] : "";
} else { } else {
return mixin.name; return (mixin.name != "withBaseComponent") ? mixin.name : "";
} }
}).join(', ').replace(spaceCommaRegEx,'');//weed out no-named mixins }).filter(Boolean).join(', ');
return prettyPrintMixins; return prettyPrintMixins;
}; };
Component.describe = Component.toString(); if (debug.enabled) {
Component.describe = Component.toString();
}
//'options' is optional hash to be merged with 'defaults' in the component definition //'options' is optional hash to be merged with 'defaults' in the component definition
function Component(node, options) { function Component(node, options) {
var fnCache = {}, uuid = 0; options = options || {};
this.identity = componentId++;
if (!node) { if (!node) {
throw new Error("Component needs a node"); throw new Error("Component needs a node");
...@@ -209,45 +263,38 @@ define( ...@@ -209,45 +263,38 @@ define(
this.$node = $(node); this.$node = $(node);
} }
this.describe = this.constructor.describe; this.toString = Component.toString;
if (debug.enabled) {
this.bind = function(func) { this.describe = this.toString();
var bound; }
if (func.uuid && (bound = fnCache[func.uuid])) { //merge defaults with supplied options
return bound; //put options in attr.__proto__ to avoid merge overhead
var attr = Object.create(options);
for (var key in this.defaults) {
if (!options.hasOwnProperty(key)) {
attr[key] = this.defaults[key];
} }
}
this.attr = attr;
var bindArgs = utils.toArray(arguments, 1); Object.keys(this.defaults || {}).forEach(function(key) {
bindArgs.unshift(this); //prepend context
bound = func.bind.apply(func, bindArgs);
bound.target = func;
func.uuid = uuid++;
fnCache[func.uuid] = bound;
return bound;
};
//merge defaults with supplied options
this.attr = utils.merge(this.defaults, options);
this.defaults && Object.keys(this.defaults).forEach(function(key) {
if (this.defaults[key] === null && this.attr[key] === null) { if (this.defaults[key] === null && this.attr[key] === null) {
throw new Error('Required attribute "' + key + '" not specified in attachTo for component "' + this.describe + '".'); throw new Error('Required attribute "' + key + '" not specified in attachTo for component "' + this.toString() + '".');
} }
}, this); }, this);
this.initialize.call(this, options || {}); this.initialize.call(this, options);
this.trigger('componentInitialized');
} }
Component.attachTo = attachTo; Component.attachTo = attachTo;
Component.teardownAll = teardownAll; Component.teardownAll = teardownAll;
// prepend common mixins to supplied list, then mixin all flavors // prepend common mixins to supplied list, then mixin all flavors
if (debug.enabled) {
mixins.unshift(withLogging);
}
mixins.unshift(withBaseComponent, advice.withAdvice, registry.withRegistration); mixins.unshift(withBaseComponent, advice.withAdvice, registry.withRegistration);
compose.mixin(Component.prototype, mixins); compose.mixin(Component.prototype, mixins);
return Component; return Component;
......
File mode changed from 100755 to 100644
...@@ -49,7 +49,7 @@ define( ...@@ -49,7 +49,7 @@ define(
name = eventArgs[0]; name = eventArgs[0];
} }
if (window.DEBUG) { if (window.DEBUG && window.DEBUG.enabled) {
logFilter = DEBUG.events.logFilter; logFilter = DEBUG.events.logFilter;
// no regex for you, actions... // no regex for you, actions...
...@@ -68,14 +68,12 @@ define( ...@@ -68,14 +68,12 @@ define(
action, action,
'[' + name + ']', '[' + name + ']',
elemToString(elem), elemToString(elem),
component.constructor.describe, component.constructor.describe.split(' ').slice(0,3).join(' ') //two mixins only
fn && (fnName = fn.name || fn.displayName) && '-> ' + fnName
); );
} }
} }
} }
function withLogging() { function withLogging() {
this.before('trigger', function() { this.before('trigger', function() {
log('trigger', this, util.toArray(arguments)); log('trigger', this, util.toArray(arguments));
......
...@@ -16,18 +16,18 @@ define( ...@@ -16,18 +16,18 @@ define(
function parseEventArgs(instance, args) { function parseEventArgs(instance, args) {
var element, type, callback; var element, type, callback;
var end = args.length;
args = util.toArray(args); if (typeof args[end - 1] === 'function') {
end -= 1;
if (typeof args[args.length-1] === 'function') { callback = args[end];
callback = args.pop();
} }
if (typeof args[args.length-1] === 'object') { if (typeof args[end - 1] === 'object') {
args.pop(); end -= 1;
} }
if (args.length == 2) { if (end == 2) {
element = args[0]; element = args[0];
type = args[1]; type = args[1];
} else { } else {
...@@ -56,53 +56,43 @@ define( ...@@ -56,53 +56,43 @@ define(
(this.reset = function() { (this.reset = function() {
this.components = []; this.components = [];
this.allInstances = []; this.allInstances = {};
this.events = []; this.events = [];
}).call(this); }).call(this);
function ComponentInfo(component) { function ComponentInfo(component) {
this.component = component; this.component = component;
this.instances = []; this.attachedTo = [];
this.instances = {};
this.addInstance = function(instance) { this.addInstance = function(instance) {
this.throwIfInstanceExistsOnNode(instance);
var instanceInfo = new InstanceInfo(instance); var instanceInfo = new InstanceInfo(instance);
this.instances.push(instanceInfo); this.instances[instance.identity] = instanceInfo;
this.attachedTo.push(instance.node);
return instanceInfo; return instanceInfo;
} }
this.throwIfInstanceExistsOnNode = function(instance) {
this.instances.forEach(function (instanceInfo) {
if (instanceInfo.instance.$node[0] === instance.$node[0]) {
throw new Error('Instance of ' + instance.constructor + ' already exists on node ' + instance.$node[0]);
}
});
}
this.removeInstance = function(instance) { this.removeInstance = function(instance) {
var instanceInfo = this.instances.filter(function(instanceInfo) { delete this.instances[instance.identity];
return instanceInfo.instance == instance; var indexOfNode = this.attachedTo.indexOf(instance.node);
})[0]; (indexOfNode > -1) && this.attachedTo.splice(indexOfNode, 1);
var index = this.instances.indexOf(instanceInfo);
(index > -1) && this.instances.splice(index, 1);
if (!this.instances.length) { if (!Object.keys(this.instances).length) {
//if I hold no more instances remove me from registry //if I hold no more instances remove me from registry
registry.removeComponentInfo(this); registry.removeComponentInfo(this);
} }
} }
this.isAttachedTo = function(node) {
return this.attachedTo.indexOf(node) > -1;
}
} }
function InstanceInfo(instance) { function InstanceInfo(instance) {
this.instance = instance; this.instance = instance;
this.events = []; this.events = [];
this.addTrigger = function() {};
this.addBind = function(event) { this.addBind = function(event) {
this.events.push(event); this.events.push(event);
registry.events.push(event); registry.events.push(event);
...@@ -127,7 +117,7 @@ define( ...@@ -127,7 +117,7 @@ define(
var inst = component.addInstance(instance); var inst = component.addInstance(instance);
this.allInstances.push(inst); this.allInstances[instance.identity] = inst;
return component; return component;
}; };
...@@ -137,11 +127,10 @@ define( ...@@ -137,11 +127,10 @@ define(
//remove from component info //remove from component info
var componentInfo = this.findComponentInfo(instance); var componentInfo = this.findComponentInfo(instance);
componentInfo.removeInstance(instance); componentInfo && componentInfo.removeInstance(instance);
//remove from registry //remove from registry
var index = this.allInstances.indexOf(instInfo); delete this.allInstances[instance.identity];
(index > -1) && this.allInstances.splice(index, 1);
}; };
this.removeComponentInfo = function(componentInfo) { this.removeComponentInfo = function(componentInfo) {
...@@ -161,41 +150,32 @@ define( ...@@ -161,41 +150,32 @@ define(
return null; return null;
}; };
this.findInstanceInfo = function(which) { this.findInstanceInfo = function(instance) {
var testFn; return this.allInstances[instance.identity] || null;
if (which.node) {
//by instance (returns matched instance)
testFn = function(inst) {return inst.instance === which};
} else {
//by node (returns array of matches)
testFn = function(inst) {return inst.instance.node === which};
}
var matches = this.allInstances.filter(testFn);
if (!matches.length) {
return which.node ? null : [];
}
return which.node ? matches[0] : matches;
}; };
this.trigger = function() { this.findInstanceInfoByNode = function(node) {
var event = parseEventArgs(this, arguments), var result = [];
instance = registry.findInstanceInfo(this); Object.keys(this.allInstances).forEach(function(k) {
var thisInstanceInfo = this.allInstances[k];
if (instance) { if(thisInstanceInfo.instance.node === node) {
instance.addTrigger(event); result.push(thisInstanceInfo);
} }
}, this);
return result;
}; };
this.on = function(componentOn) { this.on = function(componentOn) {
var otherArgs = util.toArray(arguments, 1); var instance = registry.findInstanceInfo(this), boundCallback;
var instance = registry.findInstanceInfo(this);
var boundCallback; // unpacking arguments by hand benchmarked faster
var l = arguments.length, i = 1;
var otherArgs = new Array(l - 1);
for (; i < l; i++) otherArgs[i - 1] = arguments[i];
if (instance) { if (instance) {
boundCallback = componentOn.apply(null, otherArgs); boundCallback = componentOn.apply(null, otherArgs);
if(boundCallback) { if (boundCallback) {
otherArgs[otherArgs.length-1] = boundCallback; otherArgs[otherArgs.length-1] = boundCallback;
} }
var event = parseEventArgs(this, otherArgs); var event = parseEventArgs(this, otherArgs);
...@@ -210,8 +190,18 @@ define( ...@@ -210,8 +190,18 @@ define(
if (instance) { if (instance) {
instance.removeBind(event); instance.removeBind(event);
} }
//remove from global event registry
for (var i = 0, e; e = registry.events[i]; i++) {
if (matchEvent(e, event)) {
registry.events.splice(i, 1);
}
}
}; };
//debug tools may want to add advice to trigger
registry.trigger = new Function;
this.teardown = function() { this.teardown = function() {
registry.removeInstance(this); registry.removeInstance(this);
}; };
...@@ -221,9 +211,10 @@ define( ...@@ -221,9 +211,10 @@ define(
registry.addInstance(this); registry.addInstance(this);
}); });
this.after('trigger', registry.trigger);
this.around('on', registry.on); this.around('on', registry.on);
this.after('off', registry.off); this.after('off', registry.off);
//debug tools may want to add advice to trigger
window.DEBUG && DEBUG.enabled && this.after('trigger', registry.trigger);
this.after('teardown', {obj:registry, fnName:'teardown'}); this.after('teardown', {obj:registry, fnName:'teardown'});
}; };
......
...@@ -47,10 +47,18 @@ define( ...@@ -47,10 +47,18 @@ define(
// base; //{a:2, b:6} // base; //{a:2, b:6}
merge: function(/*obj1, obj2,....deepCopy*/) { merge: function(/*obj1, obj2,....deepCopy*/) {
var args = this.toArray(arguments); // unpacking arguments by hand benchmarked faster
var l = arguments.length,
i = 0,
args = new Array(l + 1);
for (; i < l; i++) args[i + 1] = arguments[i];
if (l === 0) {
return {};
}
//start with empty object so a copy is created //start with empty object so a copy is created
args.unshift({}); args[0] = {};
if (args[args.length - 1] === true) { if (args[args.length - 1] === true) {
//jquery extend requires deep copy as first arg //jquery extend requires deep copy as first arg
......
...@@ -56,31 +56,63 @@ define( ...@@ -56,31 +56,63 @@ define(
//****************************************************************************************** //******************************************************************************************
// Event logging // Event logging
//****************************************************************************************** //******************************************************************************************
var logLevel = 'all';
logFilter = {actions: logLevel, eventNames: logLevel}; //no filter by default var ALL = 'all'; //no filter
//no logging by default
var defaultEventNamesFilter = [];
var defaultActionsFilter = [];
var logFilter = retrieveLogFilter();
function filterEventLogsByAction(/*actions*/) { function filterEventLogsByAction(/*actions*/) {
var actions = [].slice.call(arguments, 0); var actions = [].slice.call(arguments);
logFilter.eventNames.length || (logFilter.eventNames = 'all'); logFilter.eventNames.length || (logFilter.eventNames = ALL);
logFilter.actions = actions.length ? actions : 'all'; logFilter.actions = actions.length ? actions : ALL;
saveLogFilter();
} }
function filterEventLogsByName(/*eventNames*/) { function filterEventLogsByName(/*eventNames*/) {
var eventNames = [].slice.call(arguments, 0); var eventNames = [].slice.call(arguments);
logFilter.actions.length || (logFilter.actions = 'all'); logFilter.actions.length || (logFilter.actions = ALL);
logFilter.eventNames = eventNames.length ? eventNames : 'all'; logFilter.eventNames = eventNames.length ? eventNames : ALL;
saveLogFilter();
} }
function hideAllEventLogs() { function hideAllEventLogs() {
logFilter.actions = []; logFilter.actions = [];
logFilter.eventNames = []; logFilter.eventNames = [];
saveLogFilter();
} }
function showAllEventLogs() { function showAllEventLogs() {
logFilter.actions = 'all'; logFilter.actions = ALL;
logFilter.eventNames = 'all'; logFilter.eventNames = ALL;
saveLogFilter();
}
function saveLogFilter() {
if (window.localStorage) {
localStorage.setItem('logFilter_eventNames', logFilter.eventNames);
localStorage.setItem('logFilter_actions', logFilter.actions);
}
}
function retrieveLogFilter() {
var result = {
eventNames: (window.localStorage && localStorage.getItem('logFilter_eventNames')) || defaultEventNamesFilter,
actions: (window.localStorage && localStorage.getItem('logFilter_actions')) || defaultActionsFilter
};
//reconstitute arrays
Object.keys(result).forEach(function(k) {
var thisProp = result[k];
if (typeof thisProp == 'string' && thisProp !== ALL) {
result[k] = thisProp.split(',');
}
});
return result;
} }
return { return {
...@@ -90,7 +122,7 @@ define( ...@@ -90,7 +122,7 @@ define(
if (enable && window.console) { if (enable && window.console) {
console.info('Booting in DEBUG mode'); console.info('Booting in DEBUG mode');
console.info('You can filter event logging with DEBUG.events.logAll/logNone/logByName/logByAction'); console.info('You can configure event logging with DEBUG.events.logAll()/logNone()/logByName()/logByAction()');
} }
window.DEBUG = this; window.DEBUG = this;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/** /**
* @license RequireJS text 2.0.3 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. * @license RequireJS text 2.0.10 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license. * Available via the MIT or new BSD license.
* see: http://github.com/requirejs/text for details * see: http://github.com/requirejs/text for details
*/ */
/*jslint regexp: true */ /*jslint regexp: true */
/*global require: false, XMLHttpRequest: false, ActiveXObject: false, /*global require, XMLHttpRequest, ActiveXObject,
define: false, window: false, process: false, Packages: false, define, window, process, Packages,
java: false, location: false */ java, location, Components, FileUtils */
define(['module'], function (module) { define(['module'], function (module) {
'use strict'; 'use strict';
var text, fs, var text, fs, Cc, Ci, xpcIsWindows,
progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'], progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'],
xmlRegExp = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, xmlRegExp = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,
bodyRegExp = /<body[^>]*>\s*([\s\S]+)\s*<\/body>/im, bodyRegExp = /<body[^>]*>\s*([\s\S]+)\s*<\/body>/im,
...@@ -19,11 +19,11 @@ define(['module'], function (module) { ...@@ -19,11 +19,11 @@ define(['module'], function (module) {
defaultProtocol = hasLocation && location.protocol && location.protocol.replace(/\:/, ''), defaultProtocol = hasLocation && location.protocol && location.protocol.replace(/\:/, ''),
defaultHostName = hasLocation && location.hostname, defaultHostName = hasLocation && location.hostname,
defaultPort = hasLocation && (location.port || undefined), defaultPort = hasLocation && (location.port || undefined),
buildMap = [], buildMap = {},
masterConfig = (module.config && module.config()) || {}; masterConfig = (module.config && module.config()) || {};
text = { text = {
version: '2.0.3', version: '2.0.10',
strip: function (content) { strip: function (content) {
//Strips <?xml ...?> declarations so that external SVG and XML //Strips <?xml ...?> declarations so that external SVG and XML
...@@ -83,16 +83,30 @@ define(['module'], function (module) { ...@@ -83,16 +83,30 @@ define(['module'], function (module) {
* where strip is a boolean. * where strip is a boolean.
*/ */
parseName: function (name) { parseName: function (name) {
var strip = false, index = name.indexOf("."), var modName, ext, temp,
modName = name.substring(0, index), strip = false,
index = name.indexOf("."),
isRelative = name.indexOf('./') === 0 ||
name.indexOf('../') === 0;
if (index !== -1 && (!isRelative || index > 1)) {
modName = name.substring(0, index);
ext = name.substring(index + 1, name.length); ext = name.substring(index + 1, name.length);
} else {
modName = name;
}
index = ext.indexOf("!"); temp = ext || modName;
index = temp.indexOf("!");
if (index !== -1) { if (index !== -1) {
//Pull off the strip arg. //Pull off the strip arg.
strip = ext.substring(index + 1, ext.length); strip = temp.substring(index + 1) === "strip";
strip = strip === "strip"; temp = temp.substring(0, index);
ext = ext.substring(0, index); if (ext) {
ext = temp;
} else {
modName = temp;
}
} }
return { return {
...@@ -156,11 +170,18 @@ define(['module'], function (module) { ...@@ -156,11 +170,18 @@ define(['module'], function (module) {
masterConfig.isBuild = config.isBuild; masterConfig.isBuild = config.isBuild;
var parsed = text.parseName(name), var parsed = text.parseName(name),
nonStripName = parsed.moduleName + '.' + parsed.ext, nonStripName = parsed.moduleName +
(parsed.ext ? '.' + parsed.ext : ''),
url = req.toUrl(nonStripName), url = req.toUrl(nonStripName),
useXhr = (masterConfig.useXhr) || useXhr = (masterConfig.useXhr) ||
text.useXhr; text.useXhr;
// Do not load if it is an empty: url
if (url.indexOf('empty:') === 0) {
onLoad();
return;
}
//Load the text. Use XHR if possible and in a browser. //Load the text. Use XHR if possible and in a browser.
if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) { if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) {
text.get(url, function (content) { text.get(url, function (content) {
...@@ -194,11 +215,11 @@ define(['module'], function (module) { ...@@ -194,11 +215,11 @@ define(['module'], function (module) {
writeFile: function (pluginName, moduleName, req, write, config) { writeFile: function (pluginName, moduleName, req, write, config) {
var parsed = text.parseName(moduleName), var parsed = text.parseName(moduleName),
nonStripName = parsed.moduleName + '.' + parsed.ext, extPart = parsed.ext ? '.' + parsed.ext : '',
nonStripName = parsed.moduleName + extPart,
//Use a '.js' file name so that it indicates it is a //Use a '.js' file name so that it indicates it is a
//script that can be loaded across domains. //script that can be loaded across domains.
fileName = req.toUrl(parsed.moduleName + '.' + fileName = req.toUrl(parsed.moduleName + extPart) + '.js';
parsed.ext) + '.js';
//Leverage own load() method to load plugin value, but only //Leverage own load() method to load plugin value, but only
//write out values that do not have the strip argument, //write out values that do not have the strip argument,
...@@ -222,24 +243,38 @@ define(['module'], function (module) { ...@@ -222,24 +243,38 @@ define(['module'], function (module) {
if (masterConfig.env === 'node' || (!masterConfig.env && if (masterConfig.env === 'node' || (!masterConfig.env &&
typeof process !== "undefined" && typeof process !== "undefined" &&
process.versions && process.versions &&
!!process.versions.node)) { !!process.versions.node &&
!process.versions['node-webkit'])) {
//Using special require.nodeRequire, something added by r.js. //Using special require.nodeRequire, something added by r.js.
fs = require.nodeRequire('fs'); fs = require.nodeRequire('fs');
text.get = function (url, callback) { text.get = function (url, callback, errback) {
var file = fs.readFileSync(url, 'utf8'); try {
//Remove BOM (Byte Mark Order) from utf8 files if it is there. var file = fs.readFileSync(url, 'utf8');
if (file.indexOf('\uFEFF') === 0) { //Remove BOM (Byte Mark Order) from utf8 files if it is there.
file = file.substring(1); if (file.indexOf('\uFEFF') === 0) {
file = file.substring(1);
}
callback(file);
} catch (e) {
errback(e);
} }
callback(file);
}; };
} else if (masterConfig.env === 'xhr' || (!masterConfig.env && } else if (masterConfig.env === 'xhr' || (!masterConfig.env &&
text.createXhr())) { text.createXhr())) {
text.get = function (url, callback, errback) { text.get = function (url, callback, errback, headers) {
var xhr = text.createXhr(); var xhr = text.createXhr(), header;
xhr.open('GET', url, true); xhr.open('GET', url, true);
//Allow plugins direct access to xhr headers
if (headers) {
for (header in headers) {
if (headers.hasOwnProperty(header)) {
xhr.setRequestHeader(header.toLowerCase(), headers[header]);
}
}
}
//Allow overrides specified in config //Allow overrides specified in config
if (masterConfig.onXhr) { if (masterConfig.onXhr) {
masterConfig.onXhr(xhr, url); masterConfig.onXhr(xhr, url);
...@@ -259,6 +294,10 @@ define(['module'], function (module) { ...@@ -259,6 +294,10 @@ define(['module'], function (module) {
} else { } else {
callback(xhr.responseText); callback(xhr.responseText);
} }
if (masterConfig.onXhrComplete) {
masterConfig.onXhrComplete(xhr, url);
}
} }
}; };
xhr.send(null); xhr.send(null);
...@@ -289,7 +328,9 @@ define(['module'], function (module) { ...@@ -289,7 +328,9 @@ define(['module'], function (module) {
line = line.substring(1); line = line.substring(1);
} }
stringBuffer.append(line); if (line !== null) {
stringBuffer.append(line);
}
while ((line = input.readLine()) !== null) { while ((line = input.readLine()) !== null) {
stringBuffer.append(lineSeparator); stringBuffer.append(lineSeparator);
...@@ -302,7 +343,44 @@ define(['module'], function (module) { ...@@ -302,7 +343,44 @@ define(['module'], function (module) {
} }
callback(content); callback(content);
}; };
} } else if (masterConfig.env === 'xpconnect' || (!masterConfig.env &&
typeof Components !== 'undefined' && Components.classes &&
Components.interfaces)) {
//Avert your gaze!
Cc = Components.classes,
Ci = Components.interfaces;
Components.utils['import']('resource://gre/modules/FileUtils.jsm');
xpcIsWindows = ('@mozilla.org/windows-registry-key;1' in Cc);
text.get = function (url, callback) {
var inStream, convertStream, fileObj,
readData = {};
if (xpcIsWindows) {
url = url.replace(/\//g, '\\');
}
fileObj = new FileUtils.File(url);
//XPCOM, you so crazy
try {
inStream = Cc['@mozilla.org/network/file-input-stream;1']
.createInstance(Ci.nsIFileInputStream);
inStream.init(fileObj, 1, 0, false);
convertStream = Cc['@mozilla.org/intl/converter-input-stream;1']
.createInstance(Ci.nsIConverterInputStream);
convertStream.init(inStream, "utf-8", inStream.available(),
Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
convertStream.readString(inStream.available(), readData);
convertStream.close();
inStream.close();
callback(readData.value);
} catch (e) {
throw new Error((fileObj && fileObj.path || '') + ': ' + e);
}
};
}
return text; return text;
}); });
/** vim: et:ts=4:sw=4:sts=4 /** vim: et:ts=4:sw=4:sts=4
* @license RequireJS 2.1.2 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved. * @license RequireJS 2.1.8 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license. * Available via the MIT or new BSD license.
* see: http://github.com/jrburke/requirejs for details * see: http://github.com/jrburke/requirejs for details
*/ */
//Not using strict: uneven strict support in browsers, #392, and causes //Not using strict: uneven strict support in browsers, #392, and causes
//problems with requirejs.exec()/transpiler plugins that may not be strict. //problems with requirejs.exec()/transpiler plugins that may not be strict.
/*jslint regexp: true, nomen: true, sloppy: true */ /*jslint regexp: true, nomen: true, sloppy: true */
/*global window, navigator, document, importScripts, jQuery, setTimeout, opera */ /*global window, navigator, document, importScripts, setTimeout, opera */
var requirejs, require, define; var requirejs, require, define;
(function (global) { (function (global) {
var req, s, head, baseElement, dataMain, src, var req, s, head, baseElement, dataMain, src,
interactiveScript, currentlyAddingScript, mainScript, subPath, interactiveScript, currentlyAddingScript, mainScript, subPath,
version = '2.1.2', version = '2.1.8',
commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
jsSuffixRegExp = /\.js$/, jsSuffixRegExp = /\.js$/,
...@@ -21,9 +21,8 @@ var requirejs, require, define; ...@@ -21,9 +21,8 @@ var requirejs, require, define;
ostring = op.toString, ostring = op.toString,
hasOwn = op.hasOwnProperty, hasOwn = op.hasOwnProperty,
ap = Array.prototype, ap = Array.prototype,
aps = ap.slice,
apsp = ap.splice, apsp = ap.splice,
isBrowser = !!(typeof window !== 'undefined' && navigator && document), isBrowser = !!(typeof window !== 'undefined' && navigator && window.document),
isWebWorker = !isBrowser && typeof importScripts !== 'undefined', isWebWorker = !isBrowser && typeof importScripts !== 'undefined',
//PS3 indicates loaded and complete, but need to wait for complete //PS3 indicates loaded and complete, but need to wait for complete
//specifically. Sequence is 'loading', 'loaded', execution, //specifically. Sequence is 'loading', 'loaded', execution,
...@@ -135,6 +134,10 @@ var requirejs, require, define; ...@@ -135,6 +134,10 @@ var requirejs, require, define;
return document.getElementsByTagName('script'); return document.getElementsByTagName('script');
} }
function defaultOnError(err) {
throw err;
}
//Allow getting a global that expressed in //Allow getting a global that expressed in
//dot notation, like 'a.b.c'. //dot notation, like 'a.b.c'.
function getGlobal(value) { function getGlobal(value) {
...@@ -192,15 +195,21 @@ var requirejs, require, define; ...@@ -192,15 +195,21 @@ var requirejs, require, define;
var inCheckLoaded, Module, context, handlers, var inCheckLoaded, Module, context, handlers,
checkLoadedTimeoutId, checkLoadedTimeoutId,
config = { config = {
//Defaults. Do not set a default for map
//config to speed up normalize(), which
//will run faster if there is no default.
waitSeconds: 7, waitSeconds: 7,
baseUrl: './', baseUrl: './',
paths: {}, paths: {},
pkgs: {}, pkgs: {},
shim: {}, shim: {},
map: {},
config: {} config: {}
}, },
registry = {}, registry = {},
//registry of just enabled modules, to speed
//cycle breaking code when lots of modules
//are registered, but not activated.
enabledRegistry = {},
undefEvents = {}, undefEvents = {},
defQueue = [], defQueue = [],
defined = {}, defined = {},
...@@ -296,7 +305,7 @@ var requirejs, require, define; ...@@ -296,7 +305,7 @@ var requirejs, require, define;
} }
//Apply map config if available. //Apply map config if available.
if (applyMap && (baseParts || starMap) && map) { if (applyMap && map && (baseParts || starMap)) {
nameParts = name.split('/'); nameParts = name.split('/');
for (i = nameParts.length; i > 0; i -= 1) { for (i = nameParts.length; i > 0; i -= 1) {
...@@ -495,7 +504,12 @@ var requirejs, require, define; ...@@ -495,7 +504,12 @@ var requirejs, require, define;
fn(defined[id]); fn(defined[id]);
} }
} else { } else {
getModule(depMap).on(name, fn); mod = getModule(depMap);
if (mod.error && name === 'error') {
fn(mod.error);
} else {
mod.on(name, fn);
}
} }
} }
...@@ -566,7 +580,13 @@ var requirejs, require, define; ...@@ -566,7 +580,13 @@ var requirejs, require, define;
id: mod.map.id, id: mod.map.id,
uri: mod.map.url, uri: mod.map.url,
config: function () { config: function () {
return (config.config && getOwn(config.config, mod.map.id)) || {}; var c,
pkg = getOwn(config.pkgs, mod.map.id);
// For packages, only support config targeted
// at the main module.
c = pkg ? getOwn(config.config, mod.map.id + '/' + pkg.main) :
getOwn(config.config, mod.map.id);
return c || {};
}, },
exports: defined[mod.map.id] exports: defined[mod.map.id]
}); });
...@@ -577,6 +597,7 @@ var requirejs, require, define; ...@@ -577,6 +597,7 @@ var requirejs, require, define;
function cleanRegistry(id) { function cleanRegistry(id) {
//Clean up machinery used for waiting modules. //Clean up machinery used for waiting modules.
delete registry[id]; delete registry[id];
delete enabledRegistry[id];
} }
function breakCycle(mod, traced, processed) { function breakCycle(mod, traced, processed) {
...@@ -625,7 +646,7 @@ var requirejs, require, define; ...@@ -625,7 +646,7 @@ var requirejs, require, define;
inCheckLoaded = true; inCheckLoaded = true;
//Figure out the state of all the modules. //Figure out the state of all the modules.
eachProp(registry, function (mod) { eachProp(enabledRegistry, function (mod) {
map = mod.map; map = mod.map;
modId = map.id; modId = map.id;
...@@ -806,7 +827,7 @@ var requirejs, require, define; ...@@ -806,7 +827,7 @@ var requirejs, require, define;
}, },
/** /**
* Checks is the module is ready to define itself, and if so, * Checks if the module is ready to define itself, and if so,
* define it. * define it.
*/ */
check: function () { check: function () {
...@@ -834,8 +855,13 @@ var requirejs, require, define; ...@@ -834,8 +855,13 @@ var requirejs, require, define;
if (this.depCount < 1 && !this.defined) { if (this.depCount < 1 && !this.defined) {
if (isFunction(factory)) { if (isFunction(factory)) {
//If there is an error listener, favor passing //If there is an error listener, favor passing
//to that instead of throwing an error. //to that instead of throwing an error. However,
if (this.events.error) { //only do it for define()'d modules. require
//errbacks should not be called for failures in
//their callbacks (#699). However if a global
//onError is set, use that.
if ((this.events.error && this.map.isDefine) ||
req.onError !== defaultOnError) {
try { try {
exports = context.execCb(id, factory, depExports, exports); exports = context.execCb(id, factory, depExports, exports);
} catch (e) { } catch (e) {
...@@ -863,8 +889,8 @@ var requirejs, require, define; ...@@ -863,8 +889,8 @@ var requirejs, require, define;
if (err) { if (err) {
err.requireMap = this.map; err.requireMap = this.map;
err.requireModules = [this.map.id]; err.requireModules = this.map.isDefine ? [this.map.id] : null;
err.requireType = 'define'; err.requireType = this.map.isDefine ? 'define' : 'require';
return onError((this.error = err)); return onError((this.error = err));
} }
...@@ -884,7 +910,7 @@ var requirejs, require, define; ...@@ -884,7 +910,7 @@ var requirejs, require, define;
} }
//Clean up //Clean up
delete registry[id]; cleanRegistry(id);
this.defined = true; this.defined = true;
} }
...@@ -918,8 +944,7 @@ var requirejs, require, define; ...@@ -918,8 +944,7 @@ var requirejs, require, define;
name = this.map.name, name = this.map.name,
parentName = this.map.parentMap ? this.map.parentMap.name : null, parentName = this.map.parentMap ? this.map.parentMap.name : null,
localRequire = context.makeRequire(map.parentMap, { localRequire = context.makeRequire(map.parentMap, {
enableBuildCallback: true, enableBuildCallback: true
skipMap: true
}); });
//If current map is not normalized, wait for that //If current map is not normalized, wait for that
...@@ -1017,8 +1042,11 @@ var requirejs, require, define; ...@@ -1017,8 +1042,11 @@ var requirejs, require, define;
try { try {
req.exec(text); req.exec(text);
} catch (e) { } catch (e) {
throw new Error('fromText eval for ' + moduleName + return onError(makeError('fromtexteval',
' failed: ' + e); 'fromText eval for ' + id +
' failed: ' + e,
e,
[id]));
} }
if (hasInteractive) { if (hasInteractive) {
...@@ -1048,6 +1076,7 @@ var requirejs, require, define; ...@@ -1048,6 +1076,7 @@ var requirejs, require, define;
}, },
enable: function () { enable: function () {
enabledRegistry[this.map.id] = this;
this.enabled = true; this.enabled = true;
//Set flag mentioning that the module is enabling, //Set flag mentioning that the module is enabling,
...@@ -1084,7 +1113,7 @@ var requirejs, require, define; ...@@ -1084,7 +1113,7 @@ var requirejs, require, define;
})); }));
if (this.errback) { if (this.errback) {
on(depMap, 'error', this.errback); on(depMap, 'error', bind(this, this.errback));
} }
} }
...@@ -1207,6 +1236,7 @@ var requirejs, require, define; ...@@ -1207,6 +1236,7 @@ var requirejs, require, define;
Module: Module, Module: Module,
makeModuleMap: makeModuleMap, makeModuleMap: makeModuleMap,
nextTick: req.nextTick, nextTick: req.nextTick,
onError: onError,
/** /**
* Set a configuration for the context. * Set a configuration for the context.
...@@ -1233,6 +1263,9 @@ var requirejs, require, define; ...@@ -1233,6 +1263,9 @@ var requirejs, require, define;
eachProp(cfg, function (value, prop) { eachProp(cfg, function (value, prop) {
if (objs[prop]) { if (objs[prop]) {
if (prop === 'map') { if (prop === 'map') {
if (!config.map) {
config.map = {};
}
mixin(config[prop], value, true, true); mixin(config[prop], value, true, true);
} else { } else {
mixin(config[prop], value, true); mixin(config[prop], value, true);
...@@ -1344,7 +1377,7 @@ var requirejs, require, define; ...@@ -1344,7 +1377,7 @@ var requirejs, require, define;
//Synchronous access to one module. If require.get is //Synchronous access to one module. If require.get is
//available (as in the Node adapter), prefer that. //available (as in the Node adapter), prefer that.
if (req.get) { if (req.get) {
return req.get(context, deps, relMap); return req.get(context, deps, relMap, localRequire);
} }
//Normalize module name, if it contains . or .. //Normalize module name, if it contains . or ..
...@@ -1395,16 +1428,20 @@ var requirejs, require, define; ...@@ -1395,16 +1428,20 @@ var requirejs, require, define;
* plain URLs like nameToUrl. * plain URLs like nameToUrl.
*/ */
toUrl: function (moduleNamePlusExt) { toUrl: function (moduleNamePlusExt) {
var index = moduleNamePlusExt.lastIndexOf('.'), var ext,
ext = null; index = moduleNamePlusExt.lastIndexOf('.'),
segment = moduleNamePlusExt.split('/')[0],
if (index !== -1) { isRelative = segment === '.' || segment === '..';
//Have a file extension alias, and it is not the
//dots from a relative path.
if (index !== -1 && (!isRelative || index > 1)) {
ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length); ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length);
moduleNamePlusExt = moduleNamePlusExt.substring(0, index); moduleNamePlusExt = moduleNamePlusExt.substring(0, index);
} }
return context.nameToUrl(normalize(moduleNamePlusExt, return context.nameToUrl(normalize(moduleNamePlusExt,
relMap && relMap.id, true), ext); relMap && relMap.id, true), ext, true);
}, },
defined: function (id) { defined: function (id) {
...@@ -1449,10 +1486,11 @@ var requirejs, require, define; ...@@ -1449,10 +1486,11 @@ var requirejs, require, define;
/** /**
* Called to enable a module if it is still in the registry * Called to enable a module if it is still in the registry
* awaiting enablement. parent module is passed in for context, * awaiting enablement. A second arg, parent, the parent module,
* used by the optimizer. * is passed in for context, when this method is overriden by
* the optimizer. Not shown here to keep code compact.
*/ */
enable: function (depMap, parent) { enable: function (depMap) {
var mod = getOwn(registry, depMap.id); var mod = getOwn(registry, depMap.id);
if (mod) { if (mod) {
getModule(depMap).enable(); getModule(depMap).enable();
...@@ -1522,7 +1560,7 @@ var requirejs, require, define; ...@@ -1522,7 +1560,7 @@ var requirejs, require, define;
* it is assumed to have already been normalized. This is an * it is assumed to have already been normalized. This is an
* internal API, not a public one. Use toUrl for the public API. * internal API, not a public one. Use toUrl for the public API.
*/ */
nameToUrl: function (moduleName, ext) { nameToUrl: function (moduleName, ext, skipExt) {
var paths, pkgs, pkg, pkgPath, syms, i, parentModule, url, var paths, pkgs, pkg, pkgPath, syms, i, parentModule, url,
parentPath; parentPath;
...@@ -1571,7 +1609,7 @@ var requirejs, require, define; ...@@ -1571,7 +1609,7 @@ var requirejs, require, define;
//Join the path parts together, then figure out if baseUrl is needed. //Join the path parts together, then figure out if baseUrl is needed.
url = syms.join('/'); url = syms.join('/');
url += (ext || (/\?/.test(url) ? '' : '.js')); url += (ext || (/\?/.test(url) || skipExt ? '' : '.js'));
url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url; url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url;
} }
...@@ -1587,7 +1625,7 @@ var requirejs, require, define; ...@@ -1587,7 +1625,7 @@ var requirejs, require, define;
}, },
/** /**
* Executes a module callack function. Broken out as a separate function * Executes a module callback function. Broken out as a separate function
* solely to allow the build system to sequence the files in the built * solely to allow the build system to sequence the files in the built
* layer in the right sequence. * layer in the right sequence.
* *
...@@ -1625,7 +1663,7 @@ var requirejs, require, define; ...@@ -1625,7 +1663,7 @@ var requirejs, require, define;
onScriptError: function (evt) { onScriptError: function (evt) {
var data = getScriptData(evt); var data = getScriptData(evt);
if (!hasPathFallback(data.id)) { if (!hasPathFallback(data.id)) {
return onError(makeError('scripterror', 'Script error', evt, [data.id])); return onError(makeError('scripterror', 'Script error for: ' + data.id, evt, [data.id]));
} }
} }
}; };
...@@ -1754,8 +1792,19 @@ var requirejs, require, define; ...@@ -1754,8 +1792,19 @@ var requirejs, require, define;
* function. Intercept/override it if you want custom error handling. * function. Intercept/override it if you want custom error handling.
* @param {Error} err the error object. * @param {Error} err the error object.
*/ */
req.onError = function (err) { req.onError = defaultOnError;
throw err;
/**
* Creates the node for the load command. Only used in browser envs.
*/
req.createNode = function (config, moduleName, url) {
var node = config.xhtml ?
document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :
document.createElement('script');
node.type = config.scriptType || 'text/javascript';
node.charset = 'utf-8';
node.async = true;
return node;
}; };
/** /**
...@@ -1772,12 +1821,7 @@ var requirejs, require, define; ...@@ -1772,12 +1821,7 @@ var requirejs, require, define;
node; node;
if (isBrowser) { if (isBrowser) {
//In the browser so use a script tag //In the browser so use a script tag
node = config.xhtml ? node = req.createNode(config, moduleName, url);
document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') :
document.createElement('script');
node.type = config.scriptType || 'text/javascript';
node.charset = 'utf-8';
node.async = true;
node.setAttribute('data-requirecontext', context.contextName); node.setAttribute('data-requirecontext', context.contextName);
node.setAttribute('data-requiremodule', moduleName); node.setAttribute('data-requiremodule', moduleName);
...@@ -1810,7 +1854,7 @@ var requirejs, require, define; ...@@ -1810,7 +1854,7 @@ var requirejs, require, define;
node.attachEvent('onreadystatechange', context.onScriptLoad); node.attachEvent('onreadystatechange', context.onScriptLoad);
//It would be great to add an error handler here to catch //It would be great to add an error handler here to catch
//404s in IE9+. However, onreadystatechange will fire before //404s in IE9+. However, onreadystatechange will fire before
//the error handler, so that does not help. If addEvenListener //the error handler, so that does not help. If addEventListener
//is used, then IE will fire error before load, but we cannot //is used, then IE will fire error before load, but we cannot
//use that pathway given the connect.microsoft.com issue //use that pathway given the connect.microsoft.com issue
//mentioned above about not doing the 'script execute, //mentioned above about not doing the 'script execute,
...@@ -1839,16 +1883,24 @@ var requirejs, require, define; ...@@ -1839,16 +1883,24 @@ var requirejs, require, define;
return node; return node;
} else if (isWebWorker) { } else if (isWebWorker) {
//In a web worker, use importScripts. This is not a very try {
//efficient use of importScripts, importScripts will block until //In a web worker, use importScripts. This is not a very
//its script is downloaded and evaluated. However, if web workers //efficient use of importScripts, importScripts will block until
//are in play, the expectation that a build has been done so that //its script is downloaded and evaluated. However, if web workers
//only one script needs to be loaded anyway. This may need to be //are in play, the expectation that a build has been done so that
//reevaluated if other use cases become common. //only one script needs to be loaded anyway. This may need to be
importScripts(url); //reevaluated if other use cases become common.
importScripts(url);
//Account for anonymous modules
context.completeLoad(moduleName); //Account for anonymous modules
context.completeLoad(moduleName);
} catch (e) {
context.onError(makeError('importscripts',
'importScripts failed for ' +
moduleName + ' at ' + url,
e,
[moduleName]));
}
} }
}; };
...@@ -1880,24 +1932,31 @@ var requirejs, require, define; ...@@ -1880,24 +1932,31 @@ var requirejs, require, define;
//baseUrl, if it is not already set. //baseUrl, if it is not already set.
dataMain = script.getAttribute('data-main'); dataMain = script.getAttribute('data-main');
if (dataMain) { if (dataMain) {
//Preserve dataMain in case it is a path (i.e. contains '?')
mainScript = dataMain;
//Set final baseUrl if there is not already an explicit one. //Set final baseUrl if there is not already an explicit one.
if (!cfg.baseUrl) { if (!cfg.baseUrl) {
//Pull off the directory of data-main for use as the //Pull off the directory of data-main for use as the
//baseUrl. //baseUrl.
src = dataMain.split('/'); src = mainScript.split('/');
mainScript = src.pop(); mainScript = src.pop();
subPath = src.length ? src.join('/') + '/' : './'; subPath = src.length ? src.join('/') + '/' : './';
cfg.baseUrl = subPath; cfg.baseUrl = subPath;
dataMain = mainScript;
} }
//Strip off any trailing .js since dataMain is now //Strip off any trailing .js since mainScript is now
//like a module name. //like a module name.
dataMain = dataMain.replace(jsSuffixRegExp, ''); mainScript = mainScript.replace(jsSuffixRegExp, '');
//If mainScript is still a path, fall back to dataMain
if (req.jsExtRegExp.test(mainScript)) {
mainScript = dataMain;
}
//Put the data-main script in the files to load. //Put the data-main script in the files to load.
cfg.deps = cfg.deps ? cfg.deps.concat(dataMain) : [dataMain]; cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript];
return true; return true;
} }
...@@ -1925,12 +1984,13 @@ var requirejs, require, define; ...@@ -1925,12 +1984,13 @@ var requirejs, require, define;
//This module may not have dependencies //This module may not have dependencies
if (!isArray(deps)) { if (!isArray(deps)) {
callback = deps; callback = deps;
deps = []; deps = null;
} }
//If no name, and callback is a function, then figure out if it a //If no name, and callback is a function, then figure out if it a
//CommonJS thing with dependencies. //CommonJS thing with dependencies.
if (!deps.length && isFunction(callback)) { if (!deps && isFunction(callback)) {
deps = [];
//Remove comments from the callback string, //Remove comments from the callback string,
//look for require calls, and pull them into the dependencies, //look for require calls, and pull them into the dependencies,
//but only if there are function args. //but only if there are function args.
......
...@@ -25,6 +25,6 @@ ...@@ -25,6 +25,6 @@
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p> <p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer> </footer>
<script src="bower_components/todomvc-common/base.js"></script> <script src="bower_components/todomvc-common/base.js"></script>
<script data-main="app/js/main" src="bower_components/requirejs/requirejs.js"></script> <script data-main="app/js/main" src="bower_components/requirejs/require.js"></script>
</body> </body>
</html> </html>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment