Commit 82a5bac3 authored by Kostantinos Margaritis's avatar Kostantinos Margaritis Committed by Kostantinos Margaritis

Fix demo application link and twitter handle (README included). Add articles,...

Fix demo application link and twitter handle (README included). Add articles, guides, videos and community links. Add debug mode. Upgrade depot, flight, jQuery, requirejs and dev deps. Sync bower since some deps are aready upgraded but not depicted to bower.json. Adjust flight attributes to new api. Enabled debug mode for event 'visualisation' and ensuring only serialisable data are passed to components. Moved app to page folder. Introduced new paths for cleaner deps. Upgrade karma and deps. Update karma conf according to new dependencies. Replay paths to test-main and spec-dep paths. Update specs to new jasmine-flight api. Upgrade bower components.
parent c717579f
......@@ -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 source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
/**
* @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