Commit 940324e8 authored by Sindre Sorhus's avatar Sindre Sorhus

Merge pull request #1098 from kmargaritis/flightjs-updates

Flightjs updates
parents c717579f 82a5bac3
......@@ -3,10 +3,10 @@
define([
'flight/lib/component',
'../store'
'app/store'
], function (defineComponent, dataStore) {
function stats() {
this.defaultAttrs({
this.attributes({
dataStore: dataStore
});
......
......@@ -3,11 +3,11 @@
define([
'flight/lib/component',
'../store'
'app/store'
], function (defineComponent, dataStore) {
function todos() {
var filter;
this.defaultAttrs({
this.attributes({
dataStore: dataStore
});
......
/*global DEBUG */
'use strict';
require.config({
baseUrl: './',
paths: {
jquery: 'bower_components/jquery/jquery',
jquery: 'bower_components/jquery/dist/jquery',
es5shim: 'bower_components/es5-shim/es5-shim',
es5sham: 'bower_components/es5-shim/es5-sham',
text: 'bower_components/requirejs-text/text',
flight: 'bower_components/flight',
depot: 'bower_components/depot/depot'
depot: 'bower_components/depot/depot',
app: 'app/js',
templates: 'app/templates',
ui: 'app/js/ui',
data: 'app/js/data',
},
shim: {
'app/js/app': {
'app/page/app': {
deps: ['jquery', 'es5shim', 'es5sham']
}
}
});
require(['app/js/app'], function (App) {
App.initialize();
require(['flight/lib/debug'], function (debug) {
debug.enable(true);
DEBUG.events.logAll();
require(['app/page/app'],function(App){
App.initialize();
});
});
......@@ -2,13 +2,13 @@
'use strict';
define([
'./data/todos',
'./data/stats',
'./ui/new_item',
'./ui/todo_list',
'./ui/stats',
'./ui/main_selector',
'./ui/toggle_all'
'data/todos',
'data/stats',
'ui/new_item',
'ui/todo_list',
'ui/stats',
'ui/main_selector',
'ui/toggle_all'
], function (TodosData, StatsData, NewItemUI, TodoListUI, StatsUI, MainSelectorUI, ToggleAllUI) {
var initialize = function () {
StatsData.attachTo(document);
......
......@@ -4,13 +4,13 @@
define([
'flight/lib/component',
'./with_filters',
'text!app/templates/stats.html',
'../utils'
'text!templates/stats.html',
'app/utils'
], function (defineComponent, withFilters, statsTmpl, utils) {
function stats() {
var template = utils.tmpl(statsTmpl);
this.defaultAttrs({
this.attributes({
clearCompletedSelector: '#clear-completed'
});
......
......@@ -3,14 +3,14 @@
define([
'flight/lib/component',
'text!app/templates/todo.html',
'../utils'
'text!templates/todo.html',
'app/utils'
], function (defineComponent, todoTmpl, utils) {
function todoList() {
var ENTER_KEY = 13;
var template = utils.tmpl(todoTmpl);
this.defaultAttrs({
this.attributes({
destroySelector: 'button.destroy',
toggleSelector: 'input.toggle',
labelSelector: 'label',
......
......@@ -3,7 +3,7 @@
define(function () {
return function withFilters() {
this.defaultAttrs({
this.attributes({
filterSelector: '#filters a'
});
......
......@@ -2,15 +2,15 @@
"name": "flight-todomvc",
"version": "0.0.0",
"dependencies": {
"depot": "~0.1.4",
"flight": "~1.1.0",
"jquery": "1.8.3",
"requirejs": "~2.1.5",
"depot": "~0.1.6",
"flight": "~1.3.0",
"jquery": "2.1.0",
"requirejs": "~2.1.15",
"todomvc-common": "~0.3.0",
"requirejs-text": "~2.0.10"
"requirejs-text": "~2.0.13"
},
"devDependencies": {
"jasmine-flight": "~2.1.0",
"jasmine-jquery": "~1.5.8"
"jasmine-flight": "~4.0.0",
"jasmine-jquery": "~2.0.5"
}
}
// ==========================================
// Copyright 2013 Twitter, Inc
// Licensed under The MIT License
// http://opensource.org/licenses/MIT
// ==========================================
/* Copyright 2013 Twitter, Inc. Licensed under The MIT License. http://opensource.org/licenses/MIT */
define(
[
'./compose'
'./utils'
],
function(compose) {
function(utils) {
'use strict';
var advice = {
......@@ -20,8 +16,9 @@ define(
// unpacking arguments by hand benchmarked faster
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];
for (; i < l; i++) {
args[i + 1] = arguments[i];
}
return wrapped.apply(this, args);
};
},
......@@ -49,7 +46,7 @@ define(
['before', 'after', 'around'].forEach(function(m) {
this[m] = function(method, fn) {
compose.unlockProperty(this, method, function() {
utils.mutateProperty(this, method, function() {
if (typeof this[method] == 'function') {
this[method] = advice[m](this[method], fn);
} else {
......
// ==========================================
// Copyright 2013 Twitter, Inc
// Licensed under The MIT License
// http://opensource.org/licenses/MIT
// ==========================================
/* Copyright 2013 Twitter, Inc. Licensed under The MIT License. http://opensource.org/licenses/MIT */
define(
......@@ -19,7 +15,7 @@ define(
// callback context is bound to component
var componentId = 0;
function teardownInstance(instanceInfo){
function teardownInstance(instanceInfo) {
instanceInfo.events.slice().forEach(function(event) {
var args = [event.type];
......@@ -33,7 +29,7 @@ define(
function checkSerializable(type, data) {
try {
window.postMessage(data, '*');
} catch(e) {
} 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(' ')
......@@ -41,6 +37,64 @@ define(
}
}
function initAttributes(attrs) {
var definedKeys = [], incomingKeys;
this.attr = new this.attrDef;
if (debug.enabled && window.console) {
for (var key in this.attrDef.prototype) {
definedKeys.push(key);
}
incomingKeys = Object.keys(attrs);
for (var i = incomingKeys.length - 1; i >= 0; i--) {
if (definedKeys.indexOf(incomingKeys[i]) == -1) {
console.warn('Passed unused attributes including "' + incomingKeys[i] +
'" to component "' + this.toString() + '".');
break;
}
}
}
for (var key in this.attrDef.prototype) {
if (typeof attrs[key] == 'undefined') {
if (this.attr[key] === null) {
throw new Error('Required attribute "' + key +
'" not specified in attachTo for component "' + this.toString() + '".');
}
} else {
this.attr[key] = attrs[key];
}
if (typeof this.attr[key] == 'function') {
this.attr[key] = this.attr[key].call(this);
}
}
}
function initDeprecatedAttributes(attrs) {
// merge defaults with supplied options
// put options in attr.__proto__ to avoid merge overhead
var attr = Object.create(attrs);
for (var key in this.defaults) {
if (!attrs.hasOwnProperty(key)) {
attr[key] = this.defaults[key];
}
}
this.attr = attr;
Object.keys(this.defaults || {}).forEach(function(key) {
if (this.defaults[key] === null && this.attr[key] === null) {
throw new Error('Required attribute "' + key +
'" not specified in attachTo for component "' + this.toString() + '".');
}
}, this);
}
function proxyEventTo(targetEvent) {
return function(e, data) {
$(e.target).trigger(targetEvent, data);
......@@ -90,12 +144,13 @@ define(
$element.trigger((event || type), data);
if (defaultFn && !event.isDefaultPrevented()) {
(this[defaultFn] || defaultFn).call(this);
(this[defaultFn] || defaultFn).call(this, event, data);
}
return $element;
};
this.on = function() {
var $element, type, callback, originalCb;
var lastIndex = arguments.length - 1, origin = arguments[lastIndex];
......@@ -120,7 +175,8 @@ define(
}
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');
}
callback = originalCb.bind(this);
......@@ -164,9 +220,18 @@ define(
return true;
}
}, this);
$element.off(type, callback);
} else {
// Loop through the events of `this` instance
// and unbind using the callback
registry.findInstanceInfo(this).events.forEach(function (event) {
if (type == event.type) {
$element.off(type, event.callback);
}
});
}
return $element.off(type, callback);
return $element;
};
this.resolveDelegateRules = function(ruleInfo) {
......@@ -182,17 +247,35 @@ define(
return rules;
};
this.defaultAttrs = function(defaults) {
utils.push(this.defaults, defaults, true) || (this.defaults = defaults);
};
this.select = function(attributeKey) {
return this.$node.find(this.attr[attributeKey]);
};
// New-style attributes
this.attributes = function(attrs) {
var Attributes = function() {};
if (this.attrDef) {
Attributes.prototype = new this.attrDef;
}
for (var name in attrs) {
Attributes.prototype[name] = attrs[name];
}
this.attrDef = Attributes;
};
// Deprecated attributes
this.defaultAttrs = function(defaults) {
utils.push(this.defaults, defaults, true) || (this.defaults = defaults);
};
this.initialize = function(node, attrs) {
attrs || (attrs = {});
//only assign identity if there isn't one (initialize can be called multiple times)
attrs = attrs || {};
this.identity || (this.identity = componentId++);
if (!node) {
......@@ -207,23 +290,12 @@ define(
this.$node = $(node);
}
// merge defaults with supplied options
// put options in attr.__proto__ to avoid merge overhead
var attr = Object.create(attrs);
for (var key in this.defaults) {
if (!attrs.hasOwnProperty(key)) {
attr[key] = this.defaults[key];
}
if (this.attrDef) {
initAttributes.call(this, attrs);
} else {
initDeprecatedAttributes.call(this, attrs);
}
this.attr = attr;
Object.keys(this.defaults || {}).forEach(function(key) {
if (this.defaults[key] === null && this.attr[key] === null) {
throw new Error('Required attribute "' + key + '" not specified in attachTo for component "' + this.toString() + '".');
}
}, this);
return this;
};
......
// ==========================================
// Copyright 2013 Twitter, Inc
// Licensed under The MIT License
// http://opensource.org/licenses/MIT
// ==========================================
/* Copyright 2013 Twitter, Inc. Licensed under The MIT License. http://opensource.org/licenses/MIT */
define(
......@@ -35,22 +31,13 @@ define(
});
}
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(' ')
);
}
}
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];
for (var i = 1; i < l; i++) {
args[i - 1] = arguments[i];
}
if (!selector) {
throw new Error('Component needs to be attachTo\'d a jQuery object, native node or selector string');
......@@ -91,7 +78,9 @@ define(
// unpacking arguments by hand benchmarked faster
var l = arguments.length;
var mixins = new Array(l);
for (var i = 0; i < l; i++) mixins[i] = arguments[i];
for (var i = 0; i < l; i++) {
mixins[i] = arguments[i];
}
var Component = function() {};
......@@ -107,6 +96,8 @@ define(
var newComponent = define(); //TODO: fix pretty print
var newPrototype = Object.create(Component.prototype);
newPrototype.mixedIn = [].concat(Component.prototype.mixedIn);
newPrototype.defaults = utils.merge(Component.prototype.defaults);
newPrototype.attrDef = Component.prototype.attrDef;
compose.mixin(newPrototype, arguments);
newComponent.prototype = newPrototype;
newComponent.prototype.constructor = newComponent;
......
// ==========================================
// Copyright 2013 Twitter, Inc
// Licensed under The MIT License
// http://opensource.org/licenses/MIT
// ==========================================
/* Copyright 2013 Twitter, Inc. Licensed under The MIT License. http://opensource.org/licenses/MIT */
define(
[
'./utils',
'./debug'
'./utils'
],
function(utils, debug) {
function(utils) {
'use strict';
//enumerables are shims - getOwnPropertyDescriptor shim doesn't work
var canWriteProtect = debug.enabled && !utils.isEnumerable(Object, 'getOwnPropertyDescriptor');
//whitelist of unlockable property names
var dontLock = ['mixedIn'];
var dontLock = ['mixedIn', 'attrDef'];
if (canWriteProtect) {
//IE8 getOwnPropertyDescriptor is built-in but throws exeption on non DOM objects
try {
Object.getOwnPropertyDescriptor(Object, 'keys');
} catch(e) {
canWriteProtect = false;
}
}
function setPropertyWritability(obj, isWritable) {
if (!canWriteProtect) {
return;
}
var props = Object.create(null);
Object.keys(obj).forEach(
function (key) {
if (dontLock.indexOf(key) < 0) {
var desc = Object.getOwnPropertyDescriptor(obj, key);
desc.writable = isWritable;
props[key] = desc;
}
function setWritability(obj, writable) {
Object.keys(obj).forEach(function (key) {
if (dontLock.indexOf(key) < 0) {
utils.propertyWritability(obj, key, writable);
}
);
Object.defineProperties(obj, props);
}
function unlockProperty(obj, prop, op) {
var writable;
if (!canWriteProtect || !obj.hasOwnProperty(prop)) {
op.call(obj);
return;
}
writable = Object.getOwnPropertyDescriptor(obj, prop).writable;
Object.defineProperty(obj, prop, { writable: true });
op.call(obj);
Object.defineProperty(obj, prop, { writable: writable });
});
}
function mixin(base, mixins) {
base.mixedIn = base.hasOwnProperty('mixedIn') ? base.mixedIn : [];
for (var i=0; i<mixins.length; i++) {
for (var i = 0; i < mixins.length; i++) {
if (base.mixedIn.indexOf(mixins[i]) == -1) {
setPropertyWritability(base, false);
setWritability(base, false);
mixins[i].call(base);
base.mixedIn.push(mixins[i]);
}
}
setPropertyWritability(base, true);
setWritability(base, true);
}
return {
mixin: mixin,
unlockProperty: unlockProperty
mixin: mixin
};
}
......
// ==========================================
// Copyright 2013 Twitter, Inc
// Licensed under The MIT License
// http://opensource.org/licenses/MIT
// ==========================================
/* Copyright 2013 Twitter, Inc. Licensed under The MIT License. http://opensource.org/licenses/MIT */
define(
[],
['./registry'],
function() {
function(registry) {
'use strict';
// ==========================================
......@@ -18,10 +14,10 @@ define(
function traverse(util, searchTerm, options) {
options = options || {};
var obj = options.obj || window;
var path = options.path || ((obj==window) ? 'window' : '');
var path = options.path || ((obj == window) ? 'window' : '');
var props = Object.keys(obj);
props.forEach(function(prop) {
if ((tests[util] || util)(searchTerm, obj, prop)){
if ((tests[util] || util)(searchTerm, obj, prop)) {
console.log([path, '.', prop].join(''), '->', ['(', typeof obj[prop], ')'].join(''), obj[prop]);
}
if (Object.prototype.toString.call(obj[prop]) == '[object Object]' && (obj[prop] != obj) && path.split('.').indexOf(prop) == -1) {
......@@ -107,7 +103,7 @@ define(
try {
eventNames = (window.localStorage && localStorage.getItem('logFilter_eventNames'));
actions = (window.localStorage && localStorage.getItem('logFilter_actions'));
} catch(ignored) {
} catch (ignored) {
return;
}
eventNames && (logFilter.eventNames = eventNames);
......@@ -137,6 +133,8 @@ define(
window.DEBUG = this;
},
registry: registry,
find: {
byName: byName,
byNameContains: byNameContains,
......
// ==========================================
// Copyright 2013 Twitter, Inc
// Licensed under The MIT License
// http://opensource.org/licenses/MIT
// ==========================================
define(
[
'./advice',
'./component',
'./compose',
'./logger',
'./registry',
'./utils'
],
function(advice, component, compose, logger, registry, utils) {
'use strict';
return {
advice: advice,
component: component,
compose: compose,
logger: logger,
registry: registry,
utils: utils
};
}
);
// ==========================================
// Copyright 2013 Twitter, Inc
// Licensed under The MIT License
// http://opensource.org/licenses/MIT
// ==========================================
/* Copyright 2013 Twitter, Inc. Licensed under The MIT License. http://opensource.org/licenses/MIT */
define(
......@@ -27,10 +23,12 @@ define(
}
function log(action, component, eventArgs) {
if (!window.DEBUG || !window.DEBUG.enabled) return;
if (!window.DEBUG || !window.DEBUG.enabled) {
return;
}
var name, eventType, elem, fn, payload, logFilter, toRegExp, actionLoggable, nameLoggable, info;
if (typeof eventArgs[eventArgs.length-1] == 'function') {
if (typeof eventArgs[eventArgs.length - 1] == 'function') {
fn = eventArgs.pop();
fn = fn.unbound || fn; // use unbound version if any (better info)
}
......
// ==========================================
// Copyright 2013 Twitter, Inc
// Licensed under The MIT License
// http://opensource.org/licenses/MIT
// ==========================================
/* Copyright 2013 Twitter, Inc. Licensed under The MIT License. http://opensource.org/licenses/MIT */
define(
......@@ -120,8 +116,6 @@ define(
};
this.removeInstance = function(instance) {
var index, instInfo = this.findInstanceInfo(instance);
//remove from component info
var componentInfo = this.findComponentInfo(instance);
componentInfo && componentInfo.removeInstance(instance);
......@@ -174,12 +168,14 @@ define(
// 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];
for (; i < l; i++) {
otherArgs[i - 1] = arguments[i];
}
if (instance) {
boundCallback = componentOn.apply(null, otherArgs);
if (boundCallback) {
otherArgs[otherArgs.length-1] = boundCallback;
otherArgs[otherArgs.length - 1] = boundCallback;
}
var event = parseEventArgs(this, otherArgs);
instance.addBind(event);
......
// ==========================================
// Copyright 2013 Twitter, Inc
// Licensed under The MIT License
// http://opensource.org/licenses/MIT
// ==========================================
/* Copyright 2013 Twitter, Inc. Licensed under The MIT License. http://opensource.org/licenses/MIT */
define(
[],
['./debug'],
function() {
function(debug) {
'use strict';
var arry = [];
var DEFAULT_INTERVAL = 100;
function canWriteProtect() {
var writeProtectSupported = debug.enabled && !Object.propertyIsEnumerable('getOwnPropertyDescriptor');
if (writeProtectSupported) {
//IE8 getOwnPropertyDescriptor is built-in but throws exeption on non DOM objects
try {
Object.getOwnPropertyDescriptor(Object, 'keys');
} catch (e) {
return false;
}
}
return writeProtectSupported;
}
var utils = {
isDomObj: function(obj) {
......@@ -21,7 +30,12 @@ define(
},
toArray: function(obj, from) {
return arry.slice.call(obj, from);
from = from || 0;
var len = obj.length, arr = new Array(len - from);
for (var i = from; i < len; i++) {
arr[i - from] = obj[i];
}
return arr;
},
// returns new object representing multiple objects merged together
......@@ -48,14 +62,16 @@ define(
merge: function(/*obj1, obj2,....deepCopy*/) {
// 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 {};
}
for (var i = 0; i < l; i++) {
args[i + 1] = arguments[i];
}
//start with empty object so a copy is created
args[0] = {};
......@@ -107,8 +123,10 @@ define(
return base;
},
isEnumerable: function(obj, property) {
return Object.keys(obj).indexOf(property) > -1;
// If obj.key points to an enumerable property, return its value
// If obj.key points to a non-enumerable property, return undefined
getEnumerableProperty: function(obj, key) {
return obj.propertyIsEnumerable(key) ? obj[key] : undefined;
},
// build a function from other function(s)
......@@ -120,7 +138,7 @@ define(
return function() {
var args = arguments;
for (var i = funcs.length-1; i >= 0; i--) {
for (var i = funcs.length - 1; i >= 0; i--) {
args = [funcs[i].apply(this, args)];
}
......@@ -161,7 +179,7 @@ define(
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout && clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) {
......@@ -178,7 +196,7 @@ define(
}
var context, args, timeout, throttling, more, result;
var whenDone = this.debounce(function(){
var whenDone = this.debounce(function() {
more = throttling = false;
}, wait);
......@@ -254,6 +272,29 @@ define(
return result;
};
},
propertyWritability: function(obj, prop, writable) {
if (canWriteProtect() && obj.hasOwnProperty(prop)) {
Object.defineProperty(obj, prop, { writable: writable });
}
},
// Property locking/unlocking
mutateProperty: function(obj, prop, op) {
var writable;
if (!canWriteProtect() || !obj.hasOwnProperty(prop)) {
op.call(obj);
return;
}
writable = Object.getOwnPropertyDescriptor(obj, prop).writable;
Object.defineProperty(obj, prop, { writable: true });
op.call(obj);
Object.defineProperty(obj, prop, { writable: writable });
}
};
......
This diff is collapsed.
This diff is collapsed.
/**
* @license RequireJS text 2.0.12 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved.
* @license RequireJS text 2.0.13 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license.
* see: http://github.com/requirejs/text for details
*/
......@@ -23,7 +23,7 @@ define(['module'], function (module) {
masterConfig = (module.config && module.config()) || {};
text = {
version: '2.0.12',
version: '2.0.13',
strip: function (content) {
//Strips <?xml ...?> declarations so that external SVG and XML
......@@ -85,13 +85,13 @@ define(['module'], function (module) {
parseName: function (name) {
var modName, ext, temp,
strip = false,
index = name.indexOf("."),
index = name.lastIndexOf("."),
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);
} else {
modName = name;
}
......@@ -252,7 +252,7 @@ define(['module'], function (module) {
try {
var file = fs.readFileSync(url, 'utf8');
//Remove BOM (Byte Mark Order) from utf8 files if it is there.
if (file.indexOf('\uFEFF') === 0) {
if (file[0] === '\uFEFF') {
file = file.substring(1);
}
callback(file);
......
/** vim: et:ts=4:sw=4:sts=4
* @license RequireJS 2.1.11 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved.
* @license RequireJS 2.1.15 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license.
* see: http://github.com/jrburke/requirejs for details
*/
......@@ -12,7 +12,7 @@ var requirejs, require, define;
(function (global) {
var req, s, head, baseElement, dataMain, src,
interactiveScript, currentlyAddingScript, mainScript, subPath,
version = '2.1.11',
version = '2.1.15',
commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
jsSuffixRegExp = /\.js$/,
......@@ -180,7 +180,7 @@ var requirejs, require, define;
if (typeof requirejs !== 'undefined') {
if (isFunction(requirejs)) {
//Do not overwrite and existing requirejs instance.
//Do not overwrite an existing requirejs instance.
return;
}
cfg = requirejs;
......@@ -232,21 +232,20 @@ var requirejs, require, define;
* @param {Array} ary the array of path segments.
*/
function trimDots(ary) {
var i, part, length = ary.length;
for (i = 0; i < length; i++) {
var i, part;
for (i = 0; i < ary.length; i++) {
part = ary[i];
if (part === '.') {
ary.splice(i, 1);
i -= 1;
} else if (part === '..') {
if (i === 1 && (ary[2] === '..' || ary[0] === '..')) {
//End of the line. Keep at least one non-dot
//path segment at the front so it can be mapped
//correctly to disk. Otherwise, there is likely
//no path mapping for a path starting with '..'.
//This can still fail, but catches the most reasonable
//uses of ..
break;
// If at the start, or previous value is still ..,
// keep them so that when converted to a path it may
// still work when converted to a path, even though
// as an ID it is less than ideal. In larger point
// releases, may be better to just kick out an error.
if (i === 0 || (i == 1 && ary[2] === '..') || ary[i - 1] === '..') {
continue;
} else if (i > 0) {
ary.splice(i - 1, 2);
i -= 2;
......@@ -267,43 +266,37 @@ var requirejs, require, define;
*/
function normalize(name, baseName, applyMap) {
var pkgMain, mapValue, nameParts, i, j, nameSegment, lastIndex,
foundMap, foundI, foundStarMap, starI,
baseParts = baseName && baseName.split('/'),
normalizedBaseParts = baseParts,
foundMap, foundI, foundStarMap, starI, normalizedBaseParts,
baseParts = (baseName && baseName.split('/')),
map = config.map,
starMap = map && map['*'];
//Adjust any relative paths.
if (name && name.charAt(0) === '.') {
//If have a base name, try to normalize against it,
//otherwise, assume it is a top-level require that will
//be relative to baseUrl in the end.
if (baseName) {
if (name) {
name = name.split('/');
lastIndex = name.length - 1;
// If wanting node ID compatibility, strip .js from end
// of IDs. Have to do this here, and not in nameToUrl
// because node allows either .js or non .js to map
// to same file.
if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
}
// Starts with a '.' so need the baseName
if (name[0].charAt(0) === '.' && baseParts) {
//Convert baseName to array, and lop off the last part,
//so that . matches that 'directory' and not name of the baseName's
//module. For instance, baseName of 'one/two/three', maps to
//'one/two/three.js', but we want the directory, 'one/two' for
//this normalization.
normalizedBaseParts = baseParts.slice(0, baseParts.length - 1);
name = name.split('/');
lastIndex = name.length - 1;
// If wanting node ID compatibility, strip .js from end
// of IDs. Have to do this here, and not in nameToUrl
// because node allows either .js or non .js to map
// to same file.
if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {
name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');
}
name = normalizedBaseParts.concat(name);
trimDots(name);
name = name.join('/');
} else if (name.indexOf('./') === 0) {
// No baseName, so this is ID is resolved relative
// to baseUrl, pull off the leading dot.
name = name.substring(2);
}
trimDots(name);
name = name.join('/');
}
//Apply map config if available.
......@@ -379,7 +372,13 @@ var requirejs, require, define;
//retry
pathConfig.shift();
context.require.undef(id);
context.require([id]);
//Custom require that does not do map translation, since
//ID is "absolute", already mapped/resolved.
context.makeRequire(null, {
skipMap: true
})([id]);
return true;
}
}
......@@ -445,7 +444,16 @@ var requirejs, require, define;
return normalize(name, parentName, applyMap);
});
} else {
normalizedName = normalize(name, parentName, applyMap);
// If nested plugin references, then do not try to
// normalize, as it will not normalize correctly. This
// places a restriction on resourceIds, and the longer
// term solution is not to normalize until plugins are
// loaded and all normalizations to allow for async
// loading of a loader plugin. But for now, fixes the
// common uses. Details in #1131
normalizedName = name.indexOf('!') === -1 ?
normalize(name, parentName, applyMap) :
name;
}
} else {
//A regular module.
......
......@@ -17,12 +17,13 @@ module.exports = function (config) {
// loaded without require
'bower_components/es5-shim/es5-shim.js',
'bower_components/es5-shim/es5-sham.js',
'bower_components/jquery/jquery.js',
'bower_components/jasmine-flight/lib/jasmine-flight.js',
'bower_components/jquery/dist/jquery.js',
'bower_components/jasmine-jquery/lib/jasmine-jquery.js',
'bower_components/jasmine-flight/lib/jasmine-flight.js',
// hack to load RequireJS after the shim libs
'node_modules/karma-requirejs/lib/require.js',
'node_modules/requirejs/require.js',
'node_modules/karma-requirejs/lib/adapter.js',
// loaded with require
......
......@@ -2,9 +2,9 @@
"name": "flight-todomvc",
"version": "0.0.0",
"devDependencies": {
"karma": "~0.10.1",
"karma-jasmine": "~0.1.0",
"karma-requirejs": "~0.1.0",
"karma": "~0.12.6",
"karma-jasmine": "~0.2.0",
"karma-requirejs": "~0.2.2",
"karma-chrome-launcher": "~0.1.0",
"karma-ie-launcher": "~0.1.1",
"karma-firefox-launcher": "~0.1.0",
......
......@@ -12,9 +12,9 @@ The [Flight website](http://flightjs.github.io) is a great resource for getting
Here are some links you may find helpful:
* [GitHub](https://github.com/flightjs/flight)
* [Demo Application](http://twitter.github.io/flight/demo)
* [Demo Application](http://flightjs.github.io/example-app/)
* [Installation](https://github.com/flightjs/flight/blob/master/README.md#installation)
* [Flight on Twitter](http://twitter.com/flight)
* [Flight on Twitter](https://twitter.com/flightjs)
_If you have other helpful links to share, or find any of the links above no longer work, please [let us know](https://github.com/tastejs/todomvc/issues)._
......
describeComponent('app/js/data/stats', function () {
describeComponent('data/stats', function () {
'use strict';
describe('recount without datastore', function () {
beforeEach(function () {
setupComponent({
this.setupComponent({
dataStore: new mocks.DataStore([])
});
});
......@@ -38,7 +38,7 @@ describeComponent('app/js/data/stats', function () {
describe('recount with datastore', function () {
beforeEach(function () {
setupComponent({
this.setupComponent({
dataStore: new mocks.DataStore()
});
});
......
describeComponent('app/js/data/todos', function () {
describeComponent('data/todos', function () {
'use strict';
describe('without datastore', function () {
beforeEach(function () {
this.dataStore = new mocks.DataStore([]);
setupComponent({
this.setupComponent({
dataStore: this.dataStore
});
});
......@@ -26,7 +26,7 @@ describeComponent('app/js/data/todos', function () {
describe('with datastore', function () {
beforeEach(function () {
this.dataStore = new mocks.DataStore();
setupComponent({
this.setupComponent({
dataStore: this.dataStore
});
});
......
describeComponent('app/js/ui/new_item', function () {
describeComponent('ui/new_item', function () {
'use strict';
var ENTER_KEY = 13;
beforeEach(function () {
setupComponent(readFixtures('new_todo.html'));
this.setupComponent(readFixtures('new_todo.html'));
});
it('triggers uiAddRequested on enter', function () {
......
describeComponent('app/js/ui/stats', function () {
describeComponent('ui/stats', function () {
'use strict';
beforeEach(function () {
setupComponent(readFixtures('footer.html'));
this.setupComponent(readFixtures('footer.html'));
});
it('renders when stats change', function () {
......
describeComponent('app/js/ui/toggle_all', function () {
describeComponent('ui/toggle_all', function () {
'use strict';
beforeEach(function () {
setupComponent(readFixtures('toggle_all.html'));
this.setupComponent(readFixtures('toggle_all.html'));
});
it('check the checkbox w/o remaining', function () {
......
......@@ -15,7 +15,11 @@ requirejs.config({
paths: {
flight: 'bower_components/flight',
depot: 'bower_components/depot/depot',
text: 'bower_components/requirejs-text/text'
text: 'bower_components/requirejs-text/text',
ui: 'app/js/ui',
data: 'app/js/data',
app: 'app/js',
templates: 'app/templates'
},
// ask Require.js to load these files (all our tests)
......
......@@ -1099,13 +1099,64 @@
"url": "https://github.com/flightjs/flight"
}, {
"name": "Demo Application",
"url": "http://twitter.github.io/flight/demo/"
"url": "http://flightjs.github.io/example-app/"
}, {
"name": "Installation",
"url": "https://github.com/flightjs/flight/blob/master/README.md#installation"
}, {
"name": "Collection of Flight components",
"url": "http://flight-components.jit.su/"
}, {
"name": "Flight on Twitter",
"url": "http://twitter.com/flight"
"url": "https://twitter.com/flightjs"
}]
}, {
"heading": "Articles and Guides",
"links": [{
"name": "Introducing Flight: a web application framework",
"url": "https://blog.twitter.com/2013/introducing-flight-a-web-application-framework"
}, {
"name": "Building Web Applications with Flight",
"url": "http://simplebutgood.net/building-web-applications-with-flight-part-1/"
}, {
"name": "Building a chat app with @flight",
"url": "http://blog.stefanritter.com/post/81767869139/building-a-chat-app-with-flight-part-1"
}, {
"name": "Redesigning Search at Airbnb",
"url": "http://nerds.airbnb.com/redesigning-search/"
}, {
"name": "Flight Mixins",
"url": "http://kenneth.kufluk.com/blog/2014/01/flight-mixins/"
}, {
"name": "Flight at TweetDeck",
"url": "https://blog.twitter.com/2013/flight-at-tweetdeck"
}, {
"name": "How Flight Plays Well With non-Flight JS",
"url": "http://www.retailmenot.com/corp/eng/posts/2014/08/28/how-flight-plays-well-with-non-flight-js/"
}, {
"name": "Learning to Fly — Twitter Flight and Mixins",
"url": "https://speakerdeck.com/anguscroll/learning-to-fly-twitter-flight-and-mixins-1"
}]
}, {
"heading":"Videos",
"links":[{
"name": "Dan Webb: Flight.js [JSConfUS 2013]",
"url": "https://www.youtube.com/watch?v=4WRmFp8jZjc"
}, {
"name": "MountainWest JavaScript 2014",
"url": "https://www.youtube.com/watch?v=PrcvUZGuUa8"
}]
}, {
"heading": "Community",
"links": [{
"name": "Stack Overflow",
"url": "http://stackoverflow.com/questions/tagged/twitter-flight"
}, {
"name": "Flight's Google Group",
"url": "https://groups.google.com/forum/?fromgroups#!forum/twitter-flight"
}, {
"name": "Flight on Freenode IRC (#flightjs)",
"url": "http://webchat.freenode.net/?channels=flightjs"
}]
}]
},
......
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