Commit 4da42bc1 authored by Romuald Quantin's avatar Romuald Quantin Committed by Sindre Sorhus

Close GH-901: soma.js - Fixes selenium tests #819..

parent a5d0ac74
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
"dependencies": { "dependencies": {
"todomvc-common": "~0.1.6", "todomvc-common": "~0.1.6",
"director": "~1.2.0", "director": "~1.2.0",
"soma.js": "~2.0.0", "soma.js": "~2.1.0",
"soma-template": "~0.1.8" "soma-template": "~0.2.8"
} }
} }
// //
// Generated on Sun Dec 16 2012 22:47:05 GMT-0500 (EST) by Nodejitsu, Inc (Using Codesurgeon). // Generated on Fri Dec 27 2013 12:02:11 GMT-0500 (EST) by Nodejitsu, Inc (Using Codesurgeon).
// Version 1.1.9 // Version 1.2.2
// //
(function (exports) { (function (exports) {
/* /*
* browser.js: Browser specific functionality for director. * browser.js: Browser specific functionality for director.
* *
...@@ -201,7 +200,7 @@ Router.prototype.init = function (r) { ...@@ -201,7 +200,7 @@ Router.prototype.init = function (r) {
this.handler = function(onChangeEvent) { this.handler = function(onChangeEvent) {
var newURL = onChangeEvent && onChangeEvent.newURL || window.location.hash; var newURL = onChangeEvent && onChangeEvent.newURL || window.location.hash;
var url = self.history === true ? self.getPath() : newURL.replace(/.*#/, ''); var url = self.history === true ? self.getPath() : newURL.replace(/.*#/, '');
self.dispatch('on', url); self.dispatch('on', url.charAt(0) === '/' ? url : '/' + url);
}; };
listener.init(this.handler, this.history); listener.init(this.handler, this.history);
...@@ -210,7 +209,7 @@ Router.prototype.init = function (r) { ...@@ -210,7 +209,7 @@ Router.prototype.init = function (r) {
if (dlocHashEmpty() && r) { if (dlocHashEmpty() && r) {
dloc.hash = r; dloc.hash = r;
} else if (!dlocHashEmpty()) { } else if (!dlocHashEmpty()) {
self.dispatch('on', dloc.hash.replace(/^#/, '')); self.dispatch('on', '/' + dloc.hash.replace(/^(#\/|#|\/)/, ''));
} }
} }
else { else {
...@@ -363,11 +362,16 @@ function regifyString(str, params) { ...@@ -363,11 +362,16 @@ function regifyString(str, params) {
out += str.substr(0, matches.index) + matches[0]; out += str.substr(0, matches.index) + matches[0];
} }
str = out += str.substr(last); str = out += str.substr(last);
var captures = str.match(/:([^\/]+)/ig), length; var captures = str.match(/:([^\/]+)/ig), capture, length;
if (captures) { if (captures) {
length = captures.length; length = captures.length;
for (var i = 0; i < length; i++) { for (var i = 0; i < length; i++) {
str = str.replace(captures[i], paramifyString(captures[i], params)); capture = captures[i];
if (capture.slice(0, 2) === "::") {
str = capture.slice(1);
} else {
str = str.replace(capture, paramifyString(capture, params));
}
} }
} }
return str; return str;
...@@ -485,20 +489,22 @@ Router.prototype.dispatch = function(method, path, callback) { ...@@ -485,20 +489,22 @@ Router.prototype.dispatch = function(method, path, callback) {
Router.prototype.invoke = function(fns, thisArg, callback) { Router.prototype.invoke = function(fns, thisArg, callback) {
var self = this; var self = this;
var apply;
if (this.async) { if (this.async) {
_asyncEverySeries(fns, function apply(fn, next) { apply = function(fn, next) {
if (Array.isArray(fn)) { if (Array.isArray(fn)) {
return _asyncEverySeries(fn, apply, next); return _asyncEverySeries(fn, apply, next);
} else if (typeof fn == "function") { } else if (typeof fn == "function") {
fn.apply(thisArg, fns.captures.concat(next)); fn.apply(thisArg, fns.captures.concat(next));
} }
}, function() { };
_asyncEverySeries(fns, apply, function() {
if (callback) { if (callback) {
callback.apply(thisArg, arguments); callback.apply(thisArg, arguments);
} }
}); });
} else { } else {
_every(fns, function apply(fn) { apply = function(fn) {
if (Array.isArray(fn)) { if (Array.isArray(fn)) {
return _every(fn, apply); return _every(fn, apply);
} else if (typeof fn === "function") { } else if (typeof fn === "function") {
...@@ -506,7 +512,8 @@ Router.prototype.invoke = function(fns, thisArg, callback) { ...@@ -506,7 +512,8 @@ Router.prototype.invoke = function(fns, thisArg, callback) {
} else if (typeof fn === "string" && self.resource) { } else if (typeof fn === "string" && self.resource) {
self.resource[fn].apply(thisArg, fns.captures || []); self.resource[fn].apply(thisArg, fns.captures || []);
} }
}); };
_every(fns, apply);
} }
}; };
...@@ -686,7 +693,7 @@ Router.prototype.mount = function(routes, path) { ...@@ -686,7 +693,7 @@ Router.prototype.mount = function(routes, path) {
function insertOrMount(route, local) { function insertOrMount(route, local) {
var rename = route, parts = route.split(self.delimiter), routeType = typeof routes[route], isRoute = parts[0] === "" || !self._methods[parts[0]], event = isRoute ? "on" : rename; var rename = route, parts = route.split(self.delimiter), routeType = typeof routes[route], isRoute = parts[0] === "" || !self._methods[parts[0]], event = isRoute ? "on" : rename;
if (isRoute) { if (isRoute) {
rename = rename.slice((rename.match(new RegExp(self.delimiter)) || [ "" ])[0].length); rename = rename.slice((rename.match(new RegExp("^" + self.delimiter)) || [ "" ])[0].length);
parts.shift(); parts.shift();
} }
if (isRoute && routeType === "object" && !Array.isArray(routes[route])) { if (isRoute && routeType === "object" && !Array.isArray(routes[route])) {
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
<label data-dblclick="edit(todo)">{{todo.title}}</label> <label data-dblclick="edit(todo)">{{todo.title}}</label>
<button class="destroy" data-click="remove(todo)"></button> <button class="destroy" data-click="remove(todo)"></button>
</div> </div>
<input class="edit" value="{{todo.title}}" data-keypress="update(todo)" data-blur="update(todo)"> <input class="edit" value="{{todo.title}}" data-keydown="update(todo)" data-blur="update(todo)">
</li> </li>
</ul> </ul>
</section> </section>
......
...@@ -6,12 +6,16 @@ ...@@ -6,12 +6,16 @@
todo.Router = function (dispatcher) { todo.Router = function (dispatcher) {
// create the router (director.js) // create the router (director.js)
var router = new Router().init(); var router = new Router().init().configure({
notfound: render
});
// dispatch a custom event to render the template on a route change // dispatch a custom event to render the template on a route change
router.on(/.*/, function () { router.on(/.*/, render);
function render() {
dispatcher.dispatch('render'); dispatcher.dispatch('render');
}); }
return { return {
getRoute: function () { getRoute: function () {
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
'use strict'; 'use strict';
var ENTER_KEY = 13; var ENTER_KEY = 13;
var ESCAPE_KEY = 27;
todo.MainView = function (scope, template, model, router, dispatcher) { todo.MainView = function (scope, template, model, router, dispatcher) {
...@@ -51,10 +52,14 @@ ...@@ -51,10 +52,14 @@
scope.edit = function (event, item) { scope.edit = function (event, item) {
item.editing = 'editing'; item.editing = 'editing';
template.render(); template.render();
template.element.querySelector('.edit').focus();
}; };
// template function: during edit mode, changes the value of an item after an enter key press // template function: during edit mode, changes the value of an item after an enter key press
scope.update = function (event, item) { scope.update = function (event, item) {
if (cancelEditing(event, item)) {
return;
}
var value = event.currentTarget.value.trim(); var value = event.currentTarget.value.trim();
if (event.which === ENTER_KEY || event.type === 'blur') { if (event.which === ENTER_KEY || event.type === 'blur') {
if (value) { if (value) {
...@@ -69,6 +74,19 @@ ...@@ -69,6 +74,19 @@
} }
}; };
// escape has been pressed, revert the value of the input
function cancelEditing(event, item) {
if (event.which === ESCAPE_KEY) {
event.currentTarget.value = item.title;
event.currentTarget.blur();
update();
return true;
}
else {
return false;
}
}
// save the changes to the model and dispatch a custom event to render the templates // save the changes to the model and dispatch a custom event to render the templates
function update() { function update() {
model.set(items); model.set(items);
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
"todomvc-common": "~0.1.6", "todomvc-common": "~0.1.6",
"director": "~1.2.0", "director": "~1.2.0",
"requirejs": "~2.1.5", "requirejs": "~2.1.5",
"soma.js": "~2.0.0", "soma.js": "~2.1.0",
"soma-template": "~0.1.8" "soma-template": "~0.2.8"
} }
} }
// //
// Generated on Sun Dec 16 2012 22:47:05 GMT-0500 (EST) by Nodejitsu, Inc (Using Codesurgeon). // Generated on Fri Dec 27 2013 12:02:11 GMT-0500 (EST) by Nodejitsu, Inc (Using Codesurgeon).
// Version 1.1.9 // Version 1.2.2
// //
(function (exports) { (function (exports) {
/* /*
* browser.js: Browser specific functionality for director. * browser.js: Browser specific functionality for director.
* *
...@@ -201,7 +200,7 @@ Router.prototype.init = function (r) { ...@@ -201,7 +200,7 @@ Router.prototype.init = function (r) {
this.handler = function(onChangeEvent) { this.handler = function(onChangeEvent) {
var newURL = onChangeEvent && onChangeEvent.newURL || window.location.hash; var newURL = onChangeEvent && onChangeEvent.newURL || window.location.hash;
var url = self.history === true ? self.getPath() : newURL.replace(/.*#/, ''); var url = self.history === true ? self.getPath() : newURL.replace(/.*#/, '');
self.dispatch('on', url); self.dispatch('on', url.charAt(0) === '/' ? url : '/' + url);
}; };
listener.init(this.handler, this.history); listener.init(this.handler, this.history);
...@@ -210,7 +209,7 @@ Router.prototype.init = function (r) { ...@@ -210,7 +209,7 @@ Router.prototype.init = function (r) {
if (dlocHashEmpty() && r) { if (dlocHashEmpty() && r) {
dloc.hash = r; dloc.hash = r;
} else if (!dlocHashEmpty()) { } else if (!dlocHashEmpty()) {
self.dispatch('on', dloc.hash.replace(/^#/, '')); self.dispatch('on', '/' + dloc.hash.replace(/^(#\/|#|\/)/, ''));
} }
} }
else { else {
...@@ -363,11 +362,16 @@ function regifyString(str, params) { ...@@ -363,11 +362,16 @@ function regifyString(str, params) {
out += str.substr(0, matches.index) + matches[0]; out += str.substr(0, matches.index) + matches[0];
} }
str = out += str.substr(last); str = out += str.substr(last);
var captures = str.match(/:([^\/]+)/ig), length; var captures = str.match(/:([^\/]+)/ig), capture, length;
if (captures) { if (captures) {
length = captures.length; length = captures.length;
for (var i = 0; i < length; i++) { for (var i = 0; i < length; i++) {
str = str.replace(captures[i], paramifyString(captures[i], params)); capture = captures[i];
if (capture.slice(0, 2) === "::") {
str = capture.slice(1);
} else {
str = str.replace(capture, paramifyString(capture, params));
}
} }
} }
return str; return str;
...@@ -485,20 +489,22 @@ Router.prototype.dispatch = function(method, path, callback) { ...@@ -485,20 +489,22 @@ Router.prototype.dispatch = function(method, path, callback) {
Router.prototype.invoke = function(fns, thisArg, callback) { Router.prototype.invoke = function(fns, thisArg, callback) {
var self = this; var self = this;
var apply;
if (this.async) { if (this.async) {
_asyncEverySeries(fns, function apply(fn, next) { apply = function(fn, next) {
if (Array.isArray(fn)) { if (Array.isArray(fn)) {
return _asyncEverySeries(fn, apply, next); return _asyncEverySeries(fn, apply, next);
} else if (typeof fn == "function") { } else if (typeof fn == "function") {
fn.apply(thisArg, fns.captures.concat(next)); fn.apply(thisArg, fns.captures.concat(next));
} }
}, function() { };
_asyncEverySeries(fns, apply, function() {
if (callback) { if (callback) {
callback.apply(thisArg, arguments); callback.apply(thisArg, arguments);
} }
}); });
} else { } else {
_every(fns, function apply(fn) { apply = function(fn) {
if (Array.isArray(fn)) { if (Array.isArray(fn)) {
return _every(fn, apply); return _every(fn, apply);
} else if (typeof fn === "function") { } else if (typeof fn === "function") {
...@@ -506,7 +512,8 @@ Router.prototype.invoke = function(fns, thisArg, callback) { ...@@ -506,7 +512,8 @@ Router.prototype.invoke = function(fns, thisArg, callback) {
} else if (typeof fn === "string" && self.resource) { } else if (typeof fn === "string" && self.resource) {
self.resource[fn].apply(thisArg, fns.captures || []); self.resource[fn].apply(thisArg, fns.captures || []);
} }
}); };
_every(fns, apply);
} }
}; };
...@@ -686,7 +693,7 @@ Router.prototype.mount = function(routes, path) { ...@@ -686,7 +693,7 @@ Router.prototype.mount = function(routes, path) {
function insertOrMount(route, local) { function insertOrMount(route, local) {
var rename = route, parts = route.split(self.delimiter), routeType = typeof routes[route], isRoute = parts[0] === "" || !self._methods[parts[0]], event = isRoute ? "on" : rename; var rename = route, parts = route.split(self.delimiter), routeType = typeof routes[route], isRoute = parts[0] === "" || !self._methods[parts[0]], event = isRoute ? "on" : rename;
if (isRoute) { if (isRoute) {
rename = rename.slice((rename.match(new RegExp(self.delimiter)) || [ "" ])[0].length); rename = rename.slice((rename.match(new RegExp("^" + self.delimiter)) || [ "" ])[0].length);
parts.shift(); parts.shift();
} }
if (isRoute && routeType === "object" && !Array.isArray(routes[route])) { if (isRoute && routeType === "object" && !Array.isArray(routes[route])) {
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
<label data-dblclick="edit(todo)">{{todo.title}}</label> <label data-dblclick="edit(todo)">{{todo.title}}</label>
<button class="destroy" data-click="remove(todo)"></button> <button class="destroy" data-click="remove(todo)"></button>
</div> </div>
<input class="edit" value="{{todo.title}}" data-keypress="update(todo)" data-blur="update(todo)"> <input class="edit" value="{{todo.title}}" data-keydown="update(todo)" data-blur="update(todo)">
</li> </li>
</ul> </ul>
</section> </section>
......
...@@ -8,12 +8,16 @@ ...@@ -8,12 +8,16 @@
var RouterModel = function (dispatcher) { var RouterModel = function (dispatcher) {
// create the router (director.js) // create the router (director.js)
var router = new Router().init(); var router = new Router().init().configure({
notfound: render
});
// dispatch a custom event to render the template on a route change // dispatch a custom event to render the template on a route change
router.on(/.*/, function () { router.on(/.*/, render);
function render() {
dispatcher.dispatch('render'); dispatcher.dispatch('render');
}); }
return { return {
getRoute: function () { getRoute: function () {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
define([], function () { define([], function () {
var ENTER_KEY = 13; var ENTER_KEY = 13;
var ESCAPE_KEY = 27;
var MainView = function (scope, template, model, router, dispatcher) { var MainView = function (scope, template, model, router, dispatcher) {
...@@ -54,10 +55,14 @@ ...@@ -54,10 +55,14 @@
scope.edit = function (event, item) { scope.edit = function (event, item) {
item.editing = 'editing'; item.editing = 'editing';
template.render(); template.render();
template.element.querySelector('.edit').focus();
}; };
// template function: during edit mode, changes the value of an item after an enter key press // template function: during edit mode, changes the value of an item after an enter key press
scope.update = function (event, item) { scope.update = function (event, item) {
if (cancelEditing(event, item)) {
return;
}
var value = event.currentTarget.value.trim(); var value = event.currentTarget.value.trim();
if (event.which === ENTER_KEY || event.type === 'blur') { if (event.which === ENTER_KEY || event.type === 'blur') {
if (value) { if (value) {
...@@ -72,6 +77,19 @@ ...@@ -72,6 +77,19 @@
} }
}; };
// escape has been pressed, revert the value of the input
function cancelEditing(event, item) {
if (event.which === ESCAPE_KEY) {
event.currentTarget.value = item.title;
event.currentTarget.blur();
update();
return true;
}
else {
return false;
}
}
// save the changes to the model and dispatch a custom event to render the templates // save the changes to the model and dispatch a custom event to render the templates
function update() { function update() {
model.set(items); model.set(items);
......
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