Commit 6551cbbb authored by abhinav's avatar abhinav Committed by Pascal Hartig

Added Durandal framework

parent 94dc4b24
{
"name": "todomvc-durandal",
"version": "0.0.0",
"dependencies": {
"durandal": "~1.2.0",
"sammy": "~0.7.4",
"jquery": "~1.9.1",
"knockout": "~2.2.1",
"todomvc-common": "~0.1.4",
"requirejs": "~2.1.6"
}
}
define(['./system', './viewEngine', './composition', './widget', './modalDialog', './events'],
function(system, viewEngine, composition, widget, modalDialog, Events) {
var app = {
title: 'Application',
showModal: function(obj, activationData, context) {
return modalDialog.show(obj, activationData, context);
},
showMessage: function(message, title, options) {
return modalDialog.show('./messageBox', {
message: message,
title: title || this.title,
options: options
});
},
start: function() {
var that = this;
if (that.title) {
document.title = that.title;
}
return system.defer(function (dfd) {
$(function() {
system.log('Starting Application');
dfd.resolve();
system.log('Started Application');
});
}).promise();
},
setRoot: function(root, transition, applicationHost) {
var hostElement, settings = { activate: true, transition: transition };
if (!applicationHost || typeof applicationHost == "string") {
hostElement = document.getElementById(applicationHost || 'applicationHost');
} else {
hostElement = applicationHost;
}
if (typeof root === 'string') {
if (viewEngine.isViewUrl(root)) {
settings.view = root;
} else {
settings.model = root;
}
} else {
settings.model = root;
}
composition.compose(hostElement, settings);
},
adaptToDevice: function() {
document.ontouchmove = function (event) {
event.preventDefault();
};
}
};
Events.includeIn(app);
return app;
});
\ No newline at end of file
//heavily borrowed from backbone events, augmented by signals.js, added a little of my own code, cleaned up for better readability
define(['./system'], function (system) {
var eventSplitter = /\s+/;
var Events = function() { };
var Subscription = function(owner, events) {
this.owner = owner;
this.events = events;
};
Subscription.prototype.then = function (callback, context) {
this.callback = callback || this.callback;
this.context = context || this.context;
if (!this.callback) {
return this;
}
this.owner.on(this.events, this.callback, this.context);
return this;
};
Subscription.prototype.on = Subscription.prototype.then;
Subscription.prototype.off = function () {
this.owner.off(this.events, this.callback, this.context);
return this;
};
Events.prototype.on = function(events, callback, context) {
var calls, event, list;
if (!callback) {
return new Subscription(this, events);
} else {
calls = this.callbacks || (this.callbacks = {});
events = events.split(eventSplitter);
while (event = events.shift()) {
list = calls[event] || (calls[event] = []);
list.push(callback, context);
}
return this;
}
};
Events.prototype.off = function(events, callback, context) {
var event, calls, list, i;
// No events
if (!(calls = this.callbacks)) {
return this;
}
//removing all
if (!(events || callback || context)) {
delete this.callbacks;
return this;
}
events = events ? events.split(eventSplitter) : system.keys(calls);
// Loop through the callback list, splicing where appropriate.
while (event = events.shift()) {
if (!(list = calls[event]) || !(callback || context)) {
delete calls[event];
continue;
}
for (i = list.length - 2; i >= 0; i -= 2) {
if (!(callback && list[i] !== callback || context && list[i + 1] !== context)) {
list.splice(i, 2);
}
}
}
return this;
};
Events.prototype.trigger = function(events) {
var event, calls, list, i, length, args, all, rest;
if (!(calls = this.callbacks)) {
return this;
}
rest = [];
events = events.split(eventSplitter);
for (i = 1, length = arguments.length; i < length; i++) {
rest[i - 1] = arguments[i];
}
// For each event, walk through the list of callbacks twice, first to
// trigger the event, then to trigger any `"all"` callbacks.
while (event = events.shift()) {
// Copy callback lists to prevent modification.
if (all = calls.all) {
all = all.slice();
}
if (list = calls[event]) {
list = list.slice();
}
// Execute event callbacks.
if (list) {
for (i = 0, length = list.length; i < length; i += 2) {
list[i].apply(list[i + 1] || this, rest);
}
}
// Execute "all" callbacks.
if (all) {
args = [event].concat(rest);
for (i = 0, length = all.length; i < length; i += 2) {
all[i].apply(all[i + 1] || this, args);
}
}
}
return this;
};
Events.prototype.proxy = function(events) {
var that = this;
return (function(arg) {
that.trigger(events, arg);
});
};
Events.includeIn = function(targetObject) {
targetObject.on = Events.prototype.on;
targetObject.off = Events.prototype.off;
targetObject.trigger = Events.prototype.trigger;
targetObject.proxy = Events.prototype.proxy;
};
return Events;
});
\ No newline at end of file
define(['./composition', './system', './viewModel'],
function (composition, system, viewModel) {
var contexts = {},
modalCount = 0;
function ensureModalInstance(objOrModuleId) {
return system.defer(function(dfd) {
if (typeof objOrModuleId == "string") {
system.acquire(objOrModuleId).then(function(module) {
if (typeof(module) == 'function') {
dfd.resolve(new module());
} else {
dfd.resolve(module);
}
});
} else {
dfd.resolve(objOrModuleId);
}
}).promise();
}
var modalDialog = {
currentZIndex: 1050,
getNextZIndex: function () {
return ++this.currentZIndex;
},
isModalOpen: function() {
return modalCount > 0;
},
getContext: function(name) {
return contexts[name || 'default'];
},
addContext: function(name, modalContext) {
modalContext.name = name;
contexts[name] = modalContext;
var helperName = 'show' + name.substr(0, 1).toUpperCase() + name.substr(1);
this[helperName] = function (obj, activationData) {
return this.show(obj, activationData, name);
};
},
createCompositionSettings: function(obj, modalContext) {
var settings = {
model:obj,
activate:false
};
if (modalContext.afterCompose) {
settings.afterCompose = modalContext.afterCompose;
}
return settings;
},
show: function(obj, activationData, context) {
var that = this;
var modalContext = contexts[context || 'default'];
return system.defer(function(dfd) {
ensureModalInstance(obj).then(function(instance) {
var activator = viewModel.activator();
activator.activateItem(instance, activationData).then(function (success) {
if (success) {
var modal = instance.modal = {
owner: instance,
context: modalContext,
activator: activator,
close: function () {
var args = arguments;
activator.deactivateItem(instance, true).then(function (closeSuccess) {
if (closeSuccess) {
modalCount--;
modalContext.removeHost(modal);
delete instance.modal;
dfd.resolve.apply(dfd, args);
}
});
}
};
modal.settings = that.createCompositionSettings(instance, modalContext);
modalContext.addHost(modal);
modalCount++;
composition.compose(modal.host, modal.settings);
} else {
dfd.resolve(false);
}
});
});
}).promise();
}
};
modalDialog.addContext('default', {
blockoutOpacity: .2,
removeDelay: 200,
addHost: function(modal) {
var body = $('body');
var blockout = $('<div class="modalBlockout"></div>')
.css({ 'z-index': modalDialog.getNextZIndex(), 'opacity': this.blockoutOpacity })
.appendTo(body);
var host = $('<div class="modalHost"></div>')
.css({ 'z-index': modalDialog.getNextZIndex() })
.appendTo(body);
modal.host = host.get(0);
modal.blockout = blockout.get(0);
if (!modalDialog.isModalOpen()) {
modal.oldBodyMarginRight = $("body").css("margin-right");
var html = $("html");
var oldBodyOuterWidth = body.outerWidth(true);
var oldScrollTop = html.scrollTop();
$("html").css("overflow-y", "hidden");
var newBodyOuterWidth = $("body").outerWidth(true);
body.css("margin-right", (newBodyOuterWidth - oldBodyOuterWidth + parseInt(modal.oldBodyMarginRight)) + "px");
html.scrollTop(oldScrollTop); // necessary for Firefox
$("#simplemodal-overlay").css("width", newBodyOuterWidth + "px");
}
},
removeHost: function(modal) {
$(modal.host).css('opacity', 0);
$(modal.blockout).css('opacity', 0);
setTimeout(function() {
$(modal.host).remove();
$(modal.blockout).remove();
}, this.removeDelay);
if (!modalDialog.isModalOpen()) {
var html = $("html");
var oldScrollTop = html.scrollTop(); // necessary for Firefox.
html.css("overflow-y", "").scrollTop(oldScrollTop);
$("body").css("margin-right", modal.oldBodyMarginRight);
}
},
afterCompose: function(parent, newChild, settings) {
var $child = $(newChild);
var width = $child.width();
var height = $child.height();
$child.css({
'margin-top': (-height / 2).toString() + 'px',
'margin-left': (-width / 2).toString() + 'px'
});
$(settings.model.modal.host).css('opacity', 1);
if ($(newChild).hasClass('autoclose')) {
$(settings.model.modal.blockout).click(function() {
settings.model.modal.close();
});
}
$('.autofocus', newChild).each(function() {
$(this).focus();
});
}
});
return modalDialog;
});
\ No newline at end of file
define(['require'], function (require) {
var isDebugging = false,
nativeKeys = Object.keys,
hasOwnProperty = Object.prototype.hasOwnProperty,
toString = Object.prototype.toString,
system,
treatAsIE8 = false;
//see http://patik.com/blog/complete-cross-browser-console-log/
// Tell IE9 to use its built-in console
if (Function.prototype.bind && (typeof console === 'object' || typeof console === 'function') && typeof console.log == 'object') {
try {
['log', 'info', 'warn', 'error', 'assert', 'dir', 'clear', 'profile', 'profileEnd']
.forEach(function(method) {
console[method] = this.call(console[method], console);
}, Function.prototype.bind);
} catch (ex) {
treatAsIE8 = true;
}
}
// callback for dojo's loader
// note: if you wish to use Durandal with dojo's AMD loader,
// currently you must fork the dojo source with the following
// dojo/dojo.js, line 1187, the last line of the finishExec() function:
// (add) signal("moduleLoaded", [module.result, module.mid]);
// an enhancement request has been submitted to dojo to make this
// a permanent change. To view the status of this request, visit:
// http://bugs.dojotoolkit.org/ticket/16727
if (require.on) {
require.on("moduleLoaded", function (module, mid) {
system.setModuleId(module, mid);
});
}
// callback for require.js loader
if (typeof requirejs !== 'undefined') {
requirejs.onResourceLoad = function (context, map, depArray) {
system.setModuleId(context.defined[map.id], map.id);
};
}
var noop = function() { };
var log = function() {
try {
// Modern browsers
if (typeof console != 'undefined' && typeof console.log == 'function') {
// Opera 11
if (window.opera) {
var i = 0;
while (i < arguments.length) {
console.log('Item ' + (i + 1) + ': ' + arguments[i]);
i++;
}
}
// All other modern browsers
else if ((Array.prototype.slice.call(arguments)).length == 1 && typeof Array.prototype.slice.call(arguments)[0] == 'string') {
console.log((Array.prototype.slice.call(arguments)).toString());
} else {
console.log(Array.prototype.slice.call(arguments));
}
}
// IE8
else if ((!Function.prototype.bind || treatAsIE8) && typeof console != 'undefined' && typeof console.log == 'object') {
Function.prototype.call.call(console.log, console, Array.prototype.slice.call(arguments));
}
// IE7 and lower, and other old browsers
} catch(ignore) {}
};
system = {
version:"1.2.0",
noop: noop,
getModuleId: function(obj) {
if (!obj) {
return null;
}
if (typeof obj == 'function') {
return obj.prototype.__moduleId__;
}
if (typeof obj == 'string') {
return null;
}
return obj.__moduleId__;
},
setModuleId: function (obj, id) {
if (!obj) {
return;
}
if (typeof obj == 'function') {
obj.prototype.__moduleId__ = id;
return;
}
if (typeof obj == 'string') {
return;
}
obj.__moduleId__ = id;
},
debug: function(enable) {
if (arguments.length == 1) {
isDebugging = enable;
if (isDebugging) {
this.log = log;
this.log('Debug mode enabled.');
} else {
this.log('Debug mode disabled.');
this.log = noop;
}
} else {
return isDebugging;
}
},
isArray: function(obj) {
return toString.call(obj) === '[object Array]';
},
log: noop,
defer: function(action) {
return $.Deferred(action);
},
guid: function() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
},
acquire: function() {
var modules = Array.prototype.slice.call(arguments, 0);
return this.defer(function(dfd) {
require(modules, function() {
var args = arguments;
setTimeout(function() {
dfd.resolve.apply(dfd, args);
}, 1);
});
}).promise();
}
};
system.keys = nativeKeys || function(obj) {
if (obj !== Object(obj)) {
throw new TypeError('Invalid object');
}
var keys = [];
for (var key in obj) {
if (hasOwnProperty.call(obj, key)) {
keys[keys.length] = key;
}
}
return keys;
};
return system;
});
\ No newline at end of file
define(['./system'], function (system) {
var parseMarkupCore;
if ($.parseHTML) {
parseMarkupCore = function(html) {
return $.parseHTML(html);
};
} else {
parseMarkupCore = function(html) {
return $(html).get();
};
}
return {
viewExtension: '.html',
viewPlugin: 'text',
isViewUrl: function (url) {
return url.indexOf(this.viewExtension, url.length - this.viewExtension.length) !== -1;
},
convertViewUrlToViewId: function (url) {
return url.substring(0, url.length - this.viewExtension.length);
},
convertViewIdToRequirePath: function (viewId) {
return this.viewPlugin + '!' + viewId + this.viewExtension;
},
parseMarkup: function (markup) {
var allElements = parseMarkupCore(markup);
if (allElements.length == 1) {
return allElements[0];
}
var withoutCommentsOrEmptyText = [];
for (var i = 0; i < allElements.length; i++) {
var current = allElements[i];
if (current.nodeType != 8) {
if (current.nodeType == 3) {
var result = /\S/.test(current.nodeValue);
if (!result) {
continue;
}
}
withoutCommentsOrEmptyText.push(current);
}
}
if (withoutCommentsOrEmptyText.length > 1) {
return $(withoutCommentsOrEmptyText).wrapAll('<div class="durandal-wrapper"></div>').parent().get(0);
}
return withoutCommentsOrEmptyText[0];
},
createView: function(viewId) {
var that = this;
var requirePath = this.convertViewIdToRequirePath(viewId);
return system.defer(function(dfd) {
system.acquire(requirePath).then(function(markup) {
var element = that.parseMarkup(markup);
element.setAttribute('data-view', viewId);
dfd.resolve(element);
});
}).promise();
}
};
});
\ No newline at end of file
define(['./system', './viewEngine'],
function (system, viewEngine) {
function findInElements(nodes, url) {
for (var i = 0; i < nodes.length; i++) {
var current = nodes[i];
var existingUrl = current.getAttribute('data-view');
if (existingUrl == url) {
return current;
}
}
}
function escape(str) {
return (str + '').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1");
}
return {
useConvention: function(modulesPath, viewsPath, areasPath) {
modulesPath = modulesPath || 'viewmodels';
viewsPath = viewsPath || 'views';
areasPath = areasPath || viewsPath;
var reg = new RegExp(escape(modulesPath), 'gi');
this.convertModuleIdToViewId = function (moduleId) {
return moduleId.replace(reg, viewsPath);
};
this.translateViewIdToArea = function (viewId, area) {
if (!area || area == 'partial') {
return areasPath + '/' + viewId;
}
return areasPath + '/' + area + '/' + viewId;
};
},
locateViewForObject: function(obj, elementsToSearch) {
var view;
if (obj.getView) {
view = obj.getView();
if (view) {
return this.locateView(view, null, elementsToSearch);
}
}
if (obj.viewUrl) {
return this.locateView(obj.viewUrl, null, elementsToSearch);
}
var id = system.getModuleId(obj);
if (id) {
return this.locateView(this.convertModuleIdToViewId(id), null, elementsToSearch);
}
return this.locateView(this.determineFallbackViewId(obj), null, elementsToSearch);
},
convertModuleIdToViewId: function(moduleId) {
return moduleId;
},
determineFallbackViewId: function (obj) {
var funcNameRegex = /function (.{1,})\(/;
var results = (funcNameRegex).exec((obj).constructor.toString());
var typeName = (results && results.length > 1) ? results[1] : "";
return 'views/' + typeName;
},
translateViewIdToArea: function (viewId, area) {
return viewId;
},
locateView: function(viewOrUrlOrId, area, elementsToSearch) {
if (typeof viewOrUrlOrId === 'string') {
var viewId;
if (viewEngine.isViewUrl(viewOrUrlOrId)) {
viewId = viewEngine.convertViewUrlToViewId(viewOrUrlOrId);
} else {
viewId = viewOrUrlOrId;
}
if (area) {
viewId = this.translateViewIdToArea(viewId, area);
}
if (elementsToSearch) {
var existing = findInElements(elementsToSearch, viewId);
if (existing) {
return system.defer(function(dfd) {
dfd.resolve(existing);
}).promise();
}
}
return viewEngine.createView(viewId);
}
return system.defer(function(dfd) {
dfd.resolve(viewOrUrlOrId);
}).promise();
}
};
});
\ No newline at end of file
define(['./system'], function (system) {
var viewModelBinder;
var insufficientInfoMessage = 'Insufficient Information to Bind';
var unexpectedViewMessage = 'Unexpected View Type';
function doBind(obj, view, action) {
if (!view || !obj) {
if (viewModelBinder.throwOnErrors) {
throw new Error(insufficientInfoMessage);
} else {
system.log(insufficientInfoMessage, view, obj);
}
return;
}
if (!view.getAttribute) {
if (viewModelBinder.throwOnErrors) {
throw new Error(unexpectedViewMessage);
} else {
system.log(unexpectedViewMessage, view, obj);
}
return;
}
var viewName = view.getAttribute('data-view');
try {
system.log('Binding', viewName, obj);
viewModelBinder.beforeBind(obj, view);
action();
viewModelBinder.afterBind(obj, view);
} catch (e) {
if (viewModelBinder.throwOnErrors) {
throw new Error(e.message + ';\nView: ' + viewName + ";\nModuleId: " + system.getModuleId(obj));
} else {
system.log(e.message, viewName, obj);
}
}
}
return viewModelBinder = {
beforeBind: system.noop,
afterBind:system.noop,
bindContext: function(bindingContext, view, obj) {
if (obj) {
bindingContext = bindingContext.createChildContext(obj);
}
doBind(bindingContext, view, function () {
if (obj && obj.beforeBind) {
obj.beforeBind(view);
}
ko.applyBindings(bindingContext, view);
if (obj && obj.afterBind) {
obj.afterBind(view);
}
});
},
bind: function(obj, view) {
doBind(obj, view, function () {
if (obj.beforeBind) {
obj.beforeBind(view);
}
ko.applyBindings(obj, view);
if (obj.afterBind) {
obj.afterBind(view);
}
});
}
};
});
\ No newline at end of file
define(['./system', './composition'], function (system, composition) {
var widgetPartAttribute = 'data-part',
widgetPartSelector = '[' + widgetPartAttribute + ']';
var kindModuleMaps = {},
kindViewMaps = {},
bindableSettings = ['model','view','kind'];
var widget = {
getParts: function(elements) {
var parts = {};
if (!system.isArray(elements)) {
elements = [elements];
}
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
if (element.getAttribute) {
var id = element.getAttribute(widgetPartAttribute);
if (id) {
parts[id] = element;
}
var childParts = $(widgetPartSelector, element);
for (var j = 0; j < childParts.length; j++) {
var part = childParts.get(j);
parts[part.getAttribute(widgetPartAttribute)] = part;
}
}
}
return parts;
},
getSettings: function(valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor()) || {};
if (typeof value == 'string') {
return value;
} else {
for (var attrName in value) {
if (ko.utils.arrayIndexOf(bindableSettings, attrName) != -1) {
value[attrName] = ko.utils.unwrapObservable(value[attrName]);
} else {
value[attrName] = value[attrName];
}
}
}
return value;
},
registerKind: function(kind) {
ko.bindingHandlers[kind] = {
init: function() {
return { controlsDescendantBindings: true };
},
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var settings = widget.getSettings(valueAccessor);
settings.kind = kind;
widget.create(element, settings, bindingContext);
}
};
ko.virtualElements.allowedBindings[kind] = true;
},
mapKind: function(kind, viewId, moduleId) {
if (viewId) {
kindViewMaps[kind] = viewId;
}
if (moduleId) {
kindModuleMaps[kind] = moduleId;
}
},
convertKindToModuleId: function(kind) {
return kindModuleMaps[kind] || 'durandal/widgets/' + kind + '/controller';
},
convertKindToViewId: function (kind) {
return kindViewMaps[kind] || 'durandal/widgets/' + kind + '/view';
},
beforeBind: function(element, view, settings) {
var replacementParts = widget.getParts(element);
var standardParts = widget.getParts(view);
for (var partId in replacementParts) {
$(standardParts[partId]).replaceWith(replacementParts[partId]);
}
},
createCompositionSettings: function(settings) {
if (!settings.model) {
settings.model = this.convertKindToModuleId(settings.kind);
}
if (!settings.view) {
settings.view = this.convertKindToViewId(settings.kind);
}
settings.preserveContext = true;
settings.beforeBind = this.beforeBind;
return settings;
},
create: function (element, settings, bindingContext) {
if (typeof settings == 'string') {
settings = {
kind: settings
};
}
var compositionSettings = widget.createCompositionSettings(settings);
composition.compose(element, compositionSettings, bindingContext);
}
};
ko.bindingHandlers.widget = {
init: function() {
return { controlsDescendantBindings: true };
},
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var settings = widget.getSettings(valueAccessor);
widget.create(element, settings, bindingContext);
}
};
ko.virtualElements.allowedBindings.widget = true;
return widget;
});
\ No newline at end of file
(function () {
'use strict';
// Underscore's Template Module
// Courtesy of underscorejs.org
var _ = (function (_) {
_.defaults = function (object) {
if (!object) {
return object;
}
for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
var iterable = arguments[argsIndex];
if (iterable) {
for (var key in iterable) {
if (object[key] == null) {
object[key] = iterable[key];
}
}
}
}
return object;
}
// By default, Underscore uses ERB-style template delimiters, change the
// following template settings to use alternative delimiters.
_.templateSettings = {
evaluate : /<%([\s\S]+?)%>/g,
interpolate : /<%=([\s\S]+?)%>/g,
escape : /<%-([\s\S]+?)%>/g
};
// When customizing `templateSettings`, if you don't want to define an
// interpolation, evaluation or escaping regex, we need one that is
// guaranteed not to match.
var noMatch = /(.)^/;
// Certain characters need to be escaped so that they can be put into a
// string literal.
var escapes = {
"'": "'",
'\\': '\\',
'\r': 'r',
'\n': 'n',
'\t': 't',
'\u2028': 'u2028',
'\u2029': 'u2029'
};
var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
// JavaScript micro-templating, similar to John Resig's implementation.
// Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code.
_.template = function(text, data, settings) {
var render;
settings = _.defaults({}, settings, _.templateSettings);
// Combine delimiters into one regular expression via alternation.
var matcher = new RegExp([
(settings.escape || noMatch).source,
(settings.interpolate || noMatch).source,
(settings.evaluate || noMatch).source
].join('|') + '|$', 'g');
// Compile the template source, escaping string literals appropriately.
var index = 0;
var source = "__p+='";
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
source += text.slice(index, offset)
.replace(escaper, function(match) { return '\\' + escapes[match]; });
if (escape) {
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
}
if (interpolate) {
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
}
if (evaluate) {
source += "';\n" + evaluate + "\n__p+='";
}
index = offset + match.length;
return match;
});
source += "';\n";
// If a variable is not specified, place data values in local scope.
if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
source = "var __t,__p='',__j=Array.prototype.join," +
"print=function(){__p+=__j.call(arguments,'');};\n" +
source + "return __p;\n";
try {
render = new Function(settings.variable || 'obj', '_', source);
} catch (e) {
e.source = source;
throw e;
}
if (data) return render(data, _);
var template = function(data) {
return render.call(this, data, _);
};
// Provide the compiled function source as a convenience for precompilation.
template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
return template;
};
return _;
})({});
if (location.hostname === 'todomvc.com') {
window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
}
function redirect() {
if (location.hostname === 'tastejs.github.io') {
location.href = location.href.replace('tastejs.github.io/todomvc', 'todomvc.com');
}
}
function findRoot() {
var base;
[/labs/, /\w*-examples/].forEach(function (href) {
var match = location.href.match(href);
if (!base && match) {
base = location.href.indexOf(match);
}
});
return location.href.substr(0, base);
}
function getFile(file, callback) {
if (!location.host) {
return console.info('Miss the info bar? Run TodoMVC from a server to avoid a cross-origin error.');
}
var xhr = new XMLHttpRequest();
xhr.open('GET', findRoot() + file, true);
xhr.send();
xhr.onload = function () {
if (xhr.status === 200 && callback) {
callback(xhr.responseText);
}
};
}
function Learn(learnJSON, config) {
if (!(this instanceof Learn)) {
return new Learn(learnJSON, config);
}
var template, framework;
if (typeof learnJSON !== 'object') {
try {
learnJSON = JSON.parse(learnJSON);
} catch (e) {
return;
}
}
if (config) {
template = config.template;
framework = config.framework;
}
if (!template && learnJSON.templates) {
template = learnJSON.templates.todomvc;
}
if (!framework && document.querySelector('[data-framework]')) {
framework = document.querySelector('[data-framework]').getAttribute('data-framework');
}
if (template && learnJSON[framework]) {
this.frameworkJSON = learnJSON[framework];
this.template = template;
this.append();
}
}
Learn.prototype.append = function () {
var aside = document.createElement('aside');
aside.innerHTML = _.template(this.template, this.frameworkJSON);
aside.className = 'learn';
// Localize demo links
var demoLinks = aside.querySelectorAll('.demo-link');
Array.prototype.forEach.call(demoLinks, function (demoLink) {
demoLink.setAttribute('href', findRoot() + demoLink.getAttribute('href'));
});
document.body.className = (document.body.className + ' learn-bar').trim();
document.body.insertAdjacentHTML('afterBegin', aside.outerHTML);
};
redirect();
getFile('learn.json', Learn);
})();
.splash {
text-align: center;
margin: 10% 0 0 0;
}
.splash .message {
font-size: 5em;
line-height: 1.5em;
-webkit-text-shadow: rgba(0, 0, 0, 0.5) 0px 0px 15px;
text-shadow: rgba(0, 0, 0, 0.5) 0px 0px 15px;
text-transform: uppercase;
}
.splash .icon-spinner {
text-align: center;
display: inline-block;
font-size: 5em;
margin-top: 50px;
}
.page-host {
position: relative;
top: 40px;
}
.navbar-fixed-top .navbar-inner {
padding-left: 1em;
padding-right: 1em;
}
.navbar-fixed-top .icon-home {
font-size: 18px
}
.loader {
margin: 6px 8px 4px 8px;
visibility: hidden;
}
.loader.active {
visibility: visible;
}
@media (max-width: 979px) {
.page-host {
top: 0;
}
.navbar-fixed-top {
margin-bottom: 0;
}
}
\ No newline at end of file
<!doctype html>
<html lang="en" data-framework="durandal">
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<title>Durandal • TodoMVC</title>
<link rel="stylesheet" href="bower_components/todomvc-common/base.css">
<link rel="stylesheet" href="css/app.css">
</head>
<body>
<div id="applicationHost">
<!-- This is where the shell will be loaded into by idetifying as 'applicationHost' -->
</div>
<script src="bower_components/todomvc-common/base.js"></script>
<script src="bower_components/jquery/jquery.js"></script>
<script src="bower_components/knockout/knockout.js"></script>
<script src="bower_components/sammy/sammy.js"></script>
<script src="bower_components/requirejs/require.js" data-main="../durandal/js/main.js"></script>
</body>
</html>
This diff is collapsed.
/*global define, ko */
define([
'bower_components/durandal/app'
], function (app) {
'use strict';
var ViewModel = function () {
var self = this;
// store the new todo value being entered
self.current = ko.observable();
// add a new todo, when enter key is pressed
self.add = function () {
var current = self.current().trim();
if (current) {
app.trigger('todoitem', current);
self.current('');
}
};
};
return ViewModel;
});
\ No newline at end of file
This diff is collapsed.
/*global define*/
define([
'bower_components/durandal/plugins/router',
], function (router) {
'use strict';
return {
router: router,
filter: undefined, // this is used as the global cache to figure out the filter in effect.
activate: function () {
return router.activate('todoapp');
}
};
});
\ No newline at end of file
/*global define */
define([
'js/viewmodels/shell'
], function (shell) {
'use strict';
var ViewModel = function () {
var self = this;
self.activate = function (context) {
shell.filter = context.filter;
return true;
};
};
return ViewModel;
});
\ No newline at end of file
<header id="header">
<h1>todos</h1>
<input id="new-todo" data-bind="value: current, valueUpdate: 'afterkeydown', enterKey: add" placeholder="What needs to be done?" autofocus>
</header>
This diff is collapsed.
This diff is collapsed.
<section id="todoapp">
<!--ko compose: {
model: 'js/viewmodels/entry', activate: true
}--><!--/ko-->
<div>
<!--ko compose: {
model: 'js/viewmodels/list', activate: true
}--><!--/ko-->
</div>
</section>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
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