Commit 42c943aa authored by Arthur Verschaeve's avatar Arthur Verschaeve

Migrate `olives` examples to `todomvc-app-css`

Ref #1110
parent eedd22c7
node_modules/todomvc-app-css/*
!node_modules/todomvc-app-css/index.css
node_modules/todomvc-common/*
!node_modules/todomvc-common/base.js
!node_modules/todomvc-common/base.css
node_modules/requirejs/**
!node_modules/requirejs/require.js
node_modules/emily/**
!node_modules/emily/build/Emily.js
node_modules/olives/**
!node_modules/olives/build/Olives.js
!node_modules/olives/build/src/OObject.js
!node_modules/olives/build/src/Event.plugin.js
!node_modules/olives/build/src/Bind.plugin.js
!node_modules/olives/build/src/LocalStore.js
{
"name": "todomvc-olives",
"version": "0.0.0",
"dependencies": {
"olives": "~1.6.0",
"emily": "~1.8.1",
"requirejs": "~2.1.5",
"todomvc-common": "~0.3.0"
}
}
/**
* Olives http://flams.github.com/olives
* The MIT License (MIT)
* Copyright (c) 2012-2013 Olivier Scherrer <pode.fr@gmail.com> - Olivier Wietrich <olivier.wietrich@gmail.com>
*/
define(["Tools"], function (Tools) {
"use strict";
return {
/**
* Returns a NodeList including the given dom node,
* its childNodes and its siblingNodes
* @param {HTMLElement|SVGElement} dom the dom node to start with
* @param {String} query an optional CSS selector to narrow down the query
* @returns the list of nodes
*/
getNodes: function getNodes(dom, query) {
if (this.isAcceptedType(dom)) {
if (!dom.parentNode) {
document.createDocumentFragment().appendChild(dom);
}
return dom.parentNode.querySelectorAll(query || "*");
} else {
return false;
}
},
/**
* Get a domNode's dataset attribute. If dataset doesn't exist (IE)
* then the domNode is looped through to collect them.
* @param {HTMLElement|SVGElement} dom
* @returns {Object} dataset
*/
getDataset: function getDataset(dom) {
var i=0,
l,
dataset={},
split,
join;
if (this.isAcceptedType(dom)) {
if (dom.hasOwnProperty("dataset")) {
return dom.dataset;
} else {
for (l=dom.attributes.length;i<l;i++) {
split = dom.attributes[i].name.split("-");
if (split.shift() == "data") {
dataset[join = split.join("-")] = dom.getAttribute("data-"+join);
}
}
return dataset;
}
} else {
return false;
}
},
/**
* Olives can manipulate HTMLElement and SVGElements
* This function tells if an element is one of them
* @param {Element} type
* @returns true if HTMLElement or SVGElement
*/
isAcceptedType: function isAcceptedType(type) {
if (type instanceof HTMLElement ||
type instanceof SVGElement) {
return true;
} else {
return false;
}
},
/**
* Assign a new value to an Element's property. Works with HTMLElement and SVGElement.
* @param {HTMLElement|SVGElement} node the node which property should be changed
* @param {String} property the name of the property
* @param {any} value the value to set
* @returns true if assigned
*/
setAttribute: function setAttribute(node, property, value) {
if (node instanceof HTMLElement) {
node[property] = value;
return true;
} else if (node instanceof SVGElement){
node.setAttribute(property, value);
return true;
} else {
return false;
}
},
/**
* Determine if an element matches a certain CSS selector.
* @param {Element} the parent node
* @param {String} CSS selector
* @param {Element} the node to check out
* @param true if matches
*/
matches : function matches(parent, selector, node){
return Tools.toArray(this.getNodes(parent, selector)).indexOf(node) > -1;
}
};
});
/**
* Olives http://flams.github.com/olives
* The MIT License (MIT)
* Copyright (c) 2012-2013 Olivier Scherrer <pode.fr@gmail.com> - Olivier Wietrich <olivier.wietrich@gmail.com>
*/
define(["OObject", "Tools"],
/**
* @class
* Place plugin places OObject in the DOM.
* @requires OObject, Tools
*/
function PlacePlugin(OObject, Tools) {
"use strict";
/**
* Intilialize a Place.plugin with a list of OObjects
* @param {Object} $uis a list of OObjects such as:
* {
* "header": new OObject(),
* "list": new OObject()
* }
* @Constructor
*/
return function PlacePluginConstructor($uis) {
/**
* The list of uis currently set in this place plugin
* @private
*/
var _uis = {};
/**
* Attach an OObject to this DOM element
* @param {HTML|SVGElement} node the dom node where to attach the OObject
* @param {String} the name of the OObject to attach
* @throws {NoSuchOObject} an error if there's no OObject for the given name
*/
this.place = function place(node, name) {
if (_uis[name] instanceof OObject) {
_uis[name].place(node);
} else {
throw new Error(name + " is not an OObject UI in place:"+name);
}
};
/**
* Add an OObject that can be attached to a dom element
* @param {String} the name of the OObject to add to the list
* @param {OObject} ui the OObject to add the list
* @returns {Boolean} true if the OObject was added
*/
this.set = function set(name, ui) {
if (typeof name == "string" && ui instanceof OObject) {
_uis[name] = ui;
return true;
} else {
return false;
}
};
/**
* Add multiple dom elements at once
* @param {Object} $uis a list of OObjects such as:
* {
* "header": new OObject(),
* "list": new OObject()
* }
*/
this.setAll = function setAll(uis) {
Tools.loop(uis, function (ui, name) {
this.set(name, ui);
}, this);
};
/**
* Returns an OObject from the list given its name
* @param {String} the name of the OObject to get
* @returns {OObject} OObject for the given name
*/
this.get = function get(name) {
return _uis[name];
};
this.setAll($uis);
};
});
/**
* Olives http://flams.github.com/olives
* The MIT License (MIT)
* Copyright (c) 2012-2013 Olivier Scherrer <pode.fr@gmail.com> - Olivier Wietrich <olivier.wietrich@gmail.com>
*/
define(["Tools", "DomUtils"],
/**
* @class
* Plugins is the link between the UI and your plugins.
* You can design your own plugin, declare them in your UI, and call them
* from the template, like :
* <tag data-yourPlugin="method: param"></tag>
* @see Model-Plugin for instance
* @requires Tools
*/
function Plugins(Tools, DomUtils) {
"use strict";
return function PluginsConstructor($plugins) {
/**
* The list of plugins
* @private
*/
var _plugins = {},
/**
* Just a "functionalification" of trim
* for code readability
* @private
*/
trim = function trim(string) {
return string.trim();
},
/**
* Call the plugins methods, passing them the dom node
* A phrase can be :
* <tag data-plugin='method: param, param; method:param...'/>
* the function has to call every method of the plugin
* passing it the node, and the given params
* @private
*/
applyPlugin = function applyPlugin(node, phrase, plugin) {
// Split the methods
phrase.split(";")
.forEach(function (couple) {
// Split the result between method and params
var split = couple.split(":"),
// Trim the name
method = split[0].trim(),
// And the params, if any
params = split[1] ? split[1].split(",").map(trim) : [];
// The first param must be the dom node
params.unshift(node);
if (_plugins[plugin] && _plugins[plugin][method]) {
// Call the method with the following params for instance :
// [node, "param1", "param2" .. ]
_plugins[plugin][method].apply(_plugins[plugin], params);
}
});
};
/**
* Add a plugin
*
* Note that once added, the function adds a "plugins" property to the plugin.
* It's an object that holds a name property, with the registered name of the plugin
* and an apply function, to use on new nodes that the plugin would generate
*
* @param {String} name the name of the data that the plugin should look for
* @param {Object} plugin the plugin that has the functions to execute
* @returns true if plugin successfully added.
*/
this.add = function add(name, plugin) {
var that = this,
propertyName = "plugins";
if (typeof name == "string" && typeof plugin == "object" && plugin) {
_plugins[name] = plugin;
plugin[propertyName] = {
name: name,
apply: function apply() {
return that.apply.apply(that, arguments);
}
};
return true;
} else {
return false;
}
};
/**
* Add multiple plugins at once
* @param {Object} list key is the plugin name and value is the plugin
* @returns true if correct param
*/
this.addAll = function addAll(list) {
return Tools.loop(list, function (plugin, name) {
this.add(name, plugin);
}, this);
};
/**
* Get a previously added plugin
* @param {String} name the name of the plugin
* @returns {Object} the plugin
*/
this.get = function get(name) {
return _plugins[name];
};
/**
* Delete a plugin from the list
* @param {String} name the name of the plugin
* @returns {Boolean} true if success
*/
this.del = function del(name) {
return delete _plugins[name];
};
/**
* Apply the plugins to a NodeList
* @param {HTMLElement|SVGElement} dom the dom nodes on which to apply the plugins
* @returns {Boolean} true if the param is a dom node
*/
this.apply = function apply(dom) {
var nodes;
if (DomUtils.isAcceptedType(dom)) {
nodes = DomUtils.getNodes(dom);
Tools.loop(Tools.toArray(nodes), function (node) {
Tools.loop(DomUtils.getDataset(node), function (phrase, plugin) {
applyPlugin(node, phrase, plugin);
});
});
return dom;
} else {
return false;
}
};
this.addAll($plugins);
};
});
/**
* Olives http://flams.github.com/olives
* The MIT License (MIT)
* Copyright (c) 2012-2013 Olivier Scherrer <pode.fr@gmail.com> - Olivier Wietrich <olivier.wietrich@gmail.com>
*/
define(["Observable", "Tools"],
/**
* @class
* SocketIOTransport allows for client-server eventing.
* It's based on socket.io.
*/
function SocketIOTransport(Observable, Tools) {
"use strict";
/**
* Defines the SocketIOTransport
* @private
* @param {Object} $io socket.io's object
* @returns
*/
return function SocketIOTransportConstructor($socket) {
/**
* @private
* The socket.io's socket
*/
var _socket = null;
/**
* Set the socket created by SocketIO
* @param {Object} socket the socket.io socket
* @returns true if it seems to be a socket.io socket
*/
this.setSocket = function setSocket(socket) {
if (socket && typeof socket.emit == "function") {
_socket = socket;
return true;
} else {
return false;
}
};
/**
* Get the socket, for debugging purpose
* @private
* @returns {Object} the socket
*/
this.getSocket = function getSocket() {
return _socket;
};
/**
* Subscribe to a socket event
* @param {String} event the name of the event
* @param {Function} func the function to execute when the event fires
*/
this.on = function on(event, func) {
return _socket.on(event, func);
};
/**
* Subscribe to a socket event but disconnect as soon as it fires.
* @param {String} event the name of the event
* @param {Function} func the function to execute when the event fires
*/
this.once = function once(event, func) {
return _socket.once(event, func);
};
/**
* Publish an event on the socket
* @param {String} event the event to publish
* @param data
* @param {Function} callback is the function to be called for ack
*/
this.emit = function emit(event, data, callback) {
return _socket.emit(event, data, callback);
};
/**
* Stop listening to events on a channel
* @param {String} event the event to publish
* @param data
* @param {Function} callback is the function to be called for ack
*/
this.removeListener = function removeListener(event, data, callback) {
return _socket.removeListener(event, data, callback);
};
/**
* Make a request on the node server
* @param {String} channel watch the server's documentation to see available channels
* @param data the request data, it could be anything
* @param {Function} func the callback that will get the response.
* @param {Object} scope the scope in which to execute the callback
*/
this.request = function request(channel, data, func, scope) {
if (typeof channel == "string" &&
typeof data != "undefined") {
var reqData = {
eventId: Date.now() + Math.floor(Math.random()*1e6),
data: data
},
boundCallback = function () {
if (func) {
func.apply(scope || null, arguments);
}
};
this.once(reqData.eventId, boundCallback);
this.emit(channel, reqData);
return true;
} else {
return false;
}
};
/**
* Listen to an url and get notified on new data
* @param {String} channel watch the server's documentation to see available channels
* @param data the request data, it could be anything
* @param {Function} func the callback that will get the data
* @param {Object} scope the scope in which to execute the callback
* @returns
*/
this.listen = function listen(channel, data, func, scope) {
if (typeof channel == "string" &&
typeof data != "undefined" &&
typeof func == "function") {
var reqData = {
eventId: Date.now() + Math.floor(Math.random()*1e6),
data: data,
keepAlive: true
},
boundCallback = function () {
if (func) {
func.apply(scope || null, arguments);
}
},
that = this;
this.on(reqData.eventId, boundCallback);
this.emit(channel, reqData);
return function stop() {
that.emit("disconnect-" + reqData.eventId);
that.removeListener(reqData.eventId, boundCallback);
};
} else {
return false;
}
};
/**
* Sets the socket.io
*/
this.setSocket($socket);
};
});
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>Olives • TodoMVC</title> <title>Olives • TodoMVC</title>
<link rel="stylesheet" href="bower_components/todomvc-common/base.css"> <link rel="stylesheet" href="node_modules/todomvc-common/base.css">
<link rel="stylesheet" href="node_modules/todomvc-app-css/index.css">
<link rel="stylesheet" href="css/app.css"> <link rel="stylesheet" href="css/app.css">
</head> </head>
<body> <body>
...@@ -38,10 +39,10 @@ ...@@ -38,10 +39,10 @@
<p>Created by <a href="http://github.com/podefr">Olivier Scherrer</a></p> <p>Created by <a href="http://github.com/podefr">Olivier Scherrer</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p> <p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer> </footer>
<script src="bower_components/todomvc-common/base.js"></script> <script src="node_modules/todomvc-common/base.js"></script>
<script src="bower_components/requirejs/require.js"></script> <script src="node_modules/requirejs/require.js"></script>
<script src="bower_components/emily/build/Emily.js"></script> <script src="node_modules/emily/build/Emily.js"></script>
<script src="bower_components/olives/build/Olives.js"></script> <script src="node_modules/olives/build/Olives.js"></script>
<script src="js/lib/Tools.js"></script> <script src="js/lib/Tools.js"></script>
<script src="js/uis/Input.js"></script> <script src="js/uis/Input.js"></script>
<script src="js/uis/List.js"></script> <script src="js/uis/List.js"></script>
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
'Todos/Input', 'Todos/Input',
'Todos/List', 'Todos/List',
'Todos/Controls', 'Todos/Controls',
'bower_components/olives/src/LocalStore', 'node_modules/olives/build/src/LocalStore',
'Store' 'Store'
], ],
......
...@@ -3,9 +3,9 @@ ...@@ -3,9 +3,9 @@
'use strict'; 'use strict';
define('Todos/Controls', [ define('Todos/Controls', [
'bower_components/olives/src/OObject', 'node_modules/olives/build/src/OObject',
'bower_components/olives/src/Event.plugin', 'node_modules/olives/build/src/Event.plugin',
'bower_components/olives/src/Bind.plugin', 'node_modules/olives/build/src/Bind.plugin',
'LocalStore', 'LocalStore',
'Todos/Tools' 'Todos/Tools'
], ],
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
// It's going to be called Input // It's going to be called Input
define('Todos/Input', [ define('Todos/Input', [
// It uses the Olives' OObject and the Event Plugin to listen to dom events and connect them to methods // It uses the Olives' OObject and the Event Plugin to listen to dom events and connect them to methods
'bower_components/olives/src/OObject', 'node_modules/olives/build/src/OObject',
'bower_components/olives/src/Event.plugin' 'node_modules/olives/build/src/Event.plugin'
], ],
// The Input UI // The Input UI
......
...@@ -3,9 +3,9 @@ ...@@ -3,9 +3,9 @@
'use strict'; 'use strict';
define('Todos/List', [ define('Todos/List', [
'bower_components/olives/src/OObject', 'node_modules/olives/build/src/OObject',
'bower_components/olives/src/Event.plugin', 'node_modules/olives/build/src/Event.plugin',
'bower_components/olives/src/Bind.plugin', 'node_modules/olives/build/src/Bind.plugin',
'Todos/Tools' 'Todos/Tools'
], ],
......
/** vim: et:ts=4:sw=4:sts=4 /** vim: et:ts=4:sw=4:sts=4
* @license RequireJS 2.1.15 Copyright (c) 2010-2014, The Dojo Foundation All Rights Reserved. * @license RequireJS 2.1.16 Copyright (c) 2010-2015, The Dojo Foundation All Rights Reserved.
* Available via the MIT or new BSD license. * Available via the MIT or new BSD license.
* see: http://github.com/jrburke/requirejs for details * see: http://github.com/jrburke/requirejs for details
*/ */
...@@ -12,7 +12,7 @@ var requirejs, require, define; ...@@ -12,7 +12,7 @@ var requirejs, require, define;
(function (global) { (function (global) {
var req, s, head, baseElement, dataMain, src, var req, s, head, baseElement, dataMain, src,
interactiveScript, currentlyAddingScript, mainScript, subPath, interactiveScript, currentlyAddingScript, mainScript, subPath,
version = '2.1.15', version = '2.1.16',
commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg, commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g, cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
jsSuffixRegExp = /\.js$/, jsSuffixRegExp = /\.js$/,
...@@ -1123,6 +1123,13 @@ var requirejs, require, define; ...@@ -1123,6 +1123,13 @@ var requirejs, require, define;
if (this.errback) { if (this.errback) {
on(depMap, 'error', bind(this, this.errback)); on(depMap, 'error', bind(this, this.errback));
} else if (this.events.error) {
// No direct errback on this module, but something
// else is listening for errors, so be sure to
// propagate the error correctly.
on(depMap, 'error', bind(this, function(err) {
this.emit('error', err);
}));
} }
} }
......
...@@ -12,104 +12,81 @@ button { ...@@ -12,104 +12,81 @@ button {
font-size: 100%; font-size: 100%;
vertical-align: baseline; vertical-align: baseline;
font-family: inherit; font-family: inherit;
font-weight: inherit;
color: inherit; color: inherit;
-webkit-appearance: none; -webkit-appearance: none;
-ms-appearance: none; -ms-appearance: none;
-o-appearance: none;
appearance: none; appearance: none;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
font-smoothing: antialiased;
} }
body { body {
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif; font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
line-height: 1.4em; line-height: 1.4em;
background: #eaeaea url('bg.png'); background: #f5f5f5;
color: #4d4d4d; color: #4d4d4d;
width: 550px; min-width: 230px;
max-width: 550px;
margin: 0 auto; margin: 0 auto;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased; -moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased; -ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased; font-smoothing: antialiased;
font-weight: 300;
} }
button, button,
input[type="checkbox"] { input[type="checkbox"] {
outline: none; outline: none;
}
.hidden {
display: none;
} }
#todoapp { #todoapp {
background: #fff; background: #fff;
background: rgba(255, 255, 255, 0.9);
margin: 130px 0 40px 0; margin: 130px 0 40px 0;
border: 1px solid #ccc;
position: relative; position: relative;
border-top-left-radius: 2px; box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2),
border-top-right-radius: 2px; 0 25px 50px 0 rgba(0, 0, 0, 0.1);
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
0 25px 50px 0 rgba(0, 0, 0, 0.15);
}
#todoapp:before {
content: '';
border-left: 1px solid #f5d6d6;
border-right: 1px solid #f5d6d6;
width: 2px;
position: absolute;
top: 0;
left: 40px;
height: 100%;
} }
#todoapp input::-webkit-input-placeholder { #todoapp input::-webkit-input-placeholder {
font-style: italic; font-style: italic;
font-weight: 300;
color: #e6e6e6;
} }
#todoapp input::-moz-placeholder { #todoapp input::-moz-placeholder {
font-style: italic; font-style: italic;
color: #a9a9a9; font-weight: 300;
color: #e6e6e6;
}
#todoapp input::input-placeholder {
font-style: italic;
font-weight: 300;
color: #e6e6e6;
} }
#todoapp h1 { #todoapp h1 {
position: absolute; position: absolute;
top: -120px; top: -155px;
width: 100%; width: 100%;
font-size: 70px; font-size: 100px;
font-weight: bold; font-weight: 100;
text-align: center; text-align: center;
color: #b3b3b3; color: rgba(175, 47, 47, 0.15);
color: rgba(255, 255, 255, 0.3);
text-shadow: -1px -1px rgba(0, 0, 0, 0.2);
-webkit-text-rendering: optimizeLegibility; -webkit-text-rendering: optimizeLegibility;
-moz-text-rendering: optimizeLegibility; -moz-text-rendering: optimizeLegibility;
-ms-text-rendering: optimizeLegibility; -ms-text-rendering: optimizeLegibility;
-o-text-rendering: optimizeLegibility;
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
} }
#header {
padding-top: 15px;
border-radius: inherit;
}
#header:before {
content: '';
position: absolute;
top: 0;
right: 0;
left: 0;
height: 15px;
z-index: 2;
border-bottom: 1px solid #6c615c;
background: #8d7d77;
background: -webkit-gradient(linear, left top, left bottom, from(rgba(132, 110, 100, 0.8)),to(rgba(101, 84, 76, 0.8)));
background: -webkit-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
border-top-left-radius: 1px;
border-top-right-radius: 1px;
}
#new-todo, #new-todo,
.edit { .edit {
position: relative; position: relative;
...@@ -117,6 +94,7 @@ input[type="checkbox"] { ...@@ -117,6 +94,7 @@ input[type="checkbox"] {
width: 100%; width: 100%;
font-size: 24px; font-size: 24px;
font-family: inherit; font-family: inherit;
font-weight: inherit;
line-height: 1.4em; line-height: 1.4em;
border: 0; border: 0;
outline: none; outline: none;
...@@ -124,29 +102,25 @@ input[type="checkbox"] { ...@@ -124,29 +102,25 @@ input[type="checkbox"] {
padding: 6px; padding: 6px;
border: 1px solid #999; border: 1px solid #999;
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2); box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
-moz-box-sizing: border-box;
-ms-box-sizing: border-box; -ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box; box-sizing: border-box;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased; -moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased; -ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased; font-smoothing: antialiased;
} }
#new-todo { #new-todo {
padding: 16px 16px 16px 60px; padding: 16px 16px 16px 60px;
border: none; border: none;
background: rgba(0, 0, 0, 0.02); background: rgba(0, 0, 0, 0.003);
z-index: 2; box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03);
box-shadow: none;
} }
#main { #main {
position: relative; position: relative;
z-index: 2; z-index: 2;
border-top: 1px dotted #adadad; border-top: 1px solid #e6e6e6;
} }
label[for='toggle-all'] { label[for='toggle-all'] {
...@@ -155,19 +129,19 @@ label[for='toggle-all'] { ...@@ -155,19 +129,19 @@ label[for='toggle-all'] {
#toggle-all { #toggle-all {
position: absolute; position: absolute;
top: -42px; top: -55px;
left: -4px; left: -12px;
width: 40px; width: 60px;
height: 34px;
text-align: center; text-align: center;
/* Mobile Safari */ border: none; /* Mobile Safari */
border: none;
} }
#toggle-all:before { #toggle-all:before {
content: '»'; content: '';
font-size: 28px; font-size: 22px;
color: #d9d9d9; color: #e6e6e6;
padding: 0 25px 7px; padding: 10px 27px 10px 27px;
} }
#toggle-all:checked:before { #toggle-all:checked:before {
...@@ -183,7 +157,7 @@ label[for='toggle-all'] { ...@@ -183,7 +157,7 @@ label[for='toggle-all'] {
#todo-list li { #todo-list li {
position: relative; position: relative;
font-size: 24px; font-size: 24px;
border-bottom: 1px dotted #ccc; border-bottom: 1px solid #ededed;
} }
#todo-list li:last-child { #todo-list li:last-child {
...@@ -215,28 +189,18 @@ label[for='toggle-all'] { ...@@ -215,28 +189,18 @@ label[for='toggle-all'] {
top: 0; top: 0;
bottom: 0; bottom: 0;
margin: auto 0; margin: auto 0;
/* Mobile Safari */ border: none; /* Mobile Safari */
border: none;
-webkit-appearance: none; -webkit-appearance: none;
-ms-appearance: none; -ms-appearance: none;
-o-appearance: none;
appearance: none; appearance: none;
} }
#todo-list li .toggle:after { #todo-list li .toggle:after {
content: '✔'; content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#ededed" stroke-width="3"/></svg>');
/* 40 + a couple of pixels visual adjustment */
line-height: 43px;
font-size: 20px;
color: #d9d9d9;
text-shadow: 0 -1px 0 #bfbfbf;
} }
#todo-list li .toggle:checked:after { #todo-list li .toggle:checked:after {
color: #85ada7; content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#bddad5" stroke-width="3"/><path fill="#5dc2af" d="M72 25L42 71 27 56l-4 4 20 20 34-52z"/></svg>');
text-shadow: 0 1px 0 #669991;
bottom: 1px;
position: relative;
} }
#todo-list li label { #todo-list li label {
...@@ -246,12 +210,11 @@ label[for='toggle-all'] { ...@@ -246,12 +210,11 @@ label[for='toggle-all'] {
margin-left: 45px; margin-left: 45px;
display: block; display: block;
line-height: 1.2; line-height: 1.2;
-webkit-transition: color 0.4s;
transition: color 0.4s; transition: color 0.4s;
} }
#todo-list li.completed label { #todo-list li.completed label {
color: #a9a9a9; color: #d9d9d9;
text-decoration: line-through; text-decoration: line-through;
} }
...@@ -264,21 +227,18 @@ label[for='toggle-all'] { ...@@ -264,21 +227,18 @@ label[for='toggle-all'] {
width: 40px; width: 40px;
height: 40px; height: 40px;
margin: auto 0; margin: auto 0;
font-size: 22px; font-size: 30px;
color: #a88a8a; color: #cc9a9a;
-webkit-transition: all 0.2s; margin-bottom: 11px;
transition: all 0.2s; transition: color 0.2s ease-out;
} }
#todo-list li .destroy:hover { #todo-list li .destroy:hover {
text-shadow: 0 0 1px #000, color: #af5b5e;
0 0 10px rgba(199, 107, 107, 0.8);
-webkit-transform: scale(1.3);
transform: scale(1.3);
} }
#todo-list li .destroy:after { #todo-list li .destroy:after {
content: ''; content: '×';
} }
#todo-list li:hover .destroy { #todo-list li:hover .destroy {
...@@ -295,29 +255,25 @@ label[for='toggle-all'] { ...@@ -295,29 +255,25 @@ label[for='toggle-all'] {
#footer { #footer {
color: #777; color: #777;
padding: 0 15px; padding: 10px 15px;
position: absolute;
right: 0;
bottom: -31px;
left: 0;
height: 20px; height: 20px;
z-index: 1;
text-align: center; text-align: center;
border-top: 1px solid #e6e6e6;
} }
#footer:before { #footer:before {
content: ''; content: '';
position: absolute; position: absolute;
right: 0; right: 0;
bottom: 31px; bottom: 0;
left: 0; left: 0;
height: 50px; height: 50px;
z-index: -1; overflow: hidden;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3), box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2),
0 6px 0 -3px rgba(255, 255, 255, 0.8), 0 8px 0 -3px #f6f6f6,
0 7px 1px -3px rgba(0, 0, 0, 0.3), 0 9px 1px -3px rgba(0, 0, 0, 0.2),
0 43px 0 -6px rgba(255, 255, 255, 0.8), 0 16px 0 -6px #f6f6f6,
0 44px 2px -6px rgba(0, 0, 0, 0.2); 0 17px 2px -6px rgba(0, 0, 0, 0.2);
} }
#todo-count { #todo-count {
...@@ -325,6 +281,10 @@ label[for='toggle-all'] { ...@@ -325,6 +281,10 @@ label[for='toggle-all'] {
text-align: left; text-align: left;
} }
#todo-count strong {
font-weight: 300;
}
#filters { #filters {
margin: 0; margin: 0;
padding: 0; padding: 0;
...@@ -339,49 +299,73 @@ label[for='toggle-all'] { ...@@ -339,49 +299,73 @@ label[for='toggle-all'] {
} }
#filters li a { #filters li a {
color: #83756f; color: inherit;
margin: 2px; margin: 3px;
padding: 3px 7px;
text-decoration: none; text-decoration: none;
border: 1px solid transparent;
border-radius: 3px;
}
#filters li a.selected,
#filters li a:hover {
border-color: rgba(175, 47, 47, 0.1);
} }
#filters li a.selected { #filters li a.selected {
font-weight: bold; border-color: rgba(175, 47, 47, 0.2);
} }
#clear-completed { #clear-completed,
html #clear-completed:active {
float: right; float: right;
position: relative; position: relative;
line-height: 20px; line-height: 20px;
text-decoration: none; text-decoration: none;
background: rgba(0, 0, 0, 0.1); cursor: pointer;
font-size: 11px; visibility: hidden;
padding: 0 10px; position: relative;
border-radius: 3px; }
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
#clear-completed::after {
visibility: visible;
content: 'Clear completed';
position: absolute;
top: 0;
right: 0;
white-space: nowrap;
} }
#clear-completed:hover { #clear-completed:hover::after {
background: rgba(0, 0, 0, 0.15); text-decoration: underline;
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3);
} }
#info { #info {
margin: 65px auto 0; margin: 65px auto 0;
color: #a6a6a6; color: #bfbfbf;
font-size: 12px; font-size: 10px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7); text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
text-align: center; text-align: center;
} }
#info p {
line-height: 1;
}
#info a { #info a {
color: inherit; color: inherit;
text-decoration: none;
font-weight: 400;
}
#info a:hover {
text-decoration: underline;
} }
/* /*
Hack to remove background from Mobile Safari. Hack to remove background from Mobile Safari.
Can't use it globally since it destroys checkboxes in Firefox and Opera Can't use it globally since it destroys checkboxes in Firefox
*/ */
@media screen and (-webkit-min-device-pixel-ratio:0) { @media screen and (-webkit-min-device-pixel-ratio:0) {
#toggle-all, #toggle-all,
#todo-list li .toggle { #todo-list li .toggle {
...@@ -393,10 +377,6 @@ label[for='toggle-all'] { ...@@ -393,10 +377,6 @@ label[for='toggle-all'] {
} }
#toggle-all { #toggle-all {
top: -56px;
left: -15px;
width: 65px;
height: 41px;
-webkit-transform: rotate(90deg); -webkit-transform: rotate(90deg);
transform: rotate(90deg); transform: rotate(90deg);
-webkit-appearance: none; -webkit-appearance: none;
...@@ -404,151 +384,12 @@ label[for='toggle-all'] { ...@@ -404,151 +384,12 @@ label[for='toggle-all'] {
} }
} }
.hidden { @media (max-width: 430px) {
display: none; #footer {
} height: 50px;
hr {
margin: 20px 0;
border: 0;
border-top: 1px dashed #C5C5C5;
border-bottom: 1px dashed #F7F7F7;
}
.learn a {
font-weight: normal;
text-decoration: none;
color: #b83f45;
}
.learn a:hover {
text-decoration: underline;
color: #787e7e;
}
.learn h3,
.learn h4,
.learn h5 {
margin: 10px 0;
font-weight: 500;
line-height: 1.2;
color: #000;
}
.learn h3 {
font-size: 24px;
}
.learn h4 {
font-size: 18px;
}
.learn h5 {
margin-bottom: 0;
font-size: 14px;
}
.learn ul {
padding: 0;
margin: 0 0 30px 25px;
}
.learn li {
line-height: 20px;
}
.learn p {
font-size: 15px;
font-weight: 300;
line-height: 1.3;
margin-top: 0;
margin-bottom: 0;
}
.quote {
border: none;
margin: 20px 0 60px 0;
}
.quote p {
font-style: italic;
}
.quote p:before {
content: '“';
font-size: 50px;
opacity: .15;
position: absolute;
top: -20px;
left: 3px;
}
.quote p:after {
content: '”';
font-size: 50px;
opacity: .15;
position: absolute;
bottom: -42px;
right: 3px;
}
.quote footer {
position: absolute;
bottom: -40px;
right: 0;
}
.quote footer img {
border-radius: 3px;
}
.quote footer a {
margin-left: 5px;
vertical-align: middle;
}
.speech-bubble {
position: relative;
padding: 10px;
background: rgba(0, 0, 0, .04);
border-radius: 5px;
}
.speech-bubble:after {
content: '';
position: absolute;
top: 100%;
right: 30px;
border: 13px solid transparent;
border-top-color: rgba(0, 0, 0, .04);
}
.learn-bar > .learn {
position: absolute;
width: 272px;
top: 8px;
left: -300px;
padding: 10px;
border-radius: 5px;
background-color: rgba(255, 255, 255, .6);
-webkit-transition-property: left;
transition-property: left;
-webkit-transition-duration: 500ms;
transition-duration: 500ms;
}
@media (min-width: 899px) {
.learn-bar {
width: auto;
margin: 0 0 0 300px;
}
.learn-bar > .learn {
left: 8px;
} }
.learn-bar #todoapp { #filters {
width: 550px; bottom: 10px;
margin: 130px auto 40px auto;
} }
} }
hr {
margin: 20px 0;
border: 0;
border-top: 1px dashed #c5c5c5;
border-bottom: 1px dashed #f7f7f7;
}
.learn a {
font-weight: normal;
text-decoration: none;
color: #b83f45;
}
.learn a:hover {
text-decoration: underline;
color: #787e7e;
}
.learn h3,
.learn h4,
.learn h5 {
margin: 10px 0;
font-weight: 500;
line-height: 1.2;
color: #000;
}
.learn h3 {
font-size: 24px;
}
.learn h4 {
font-size: 18px;
}
.learn h5 {
margin-bottom: 0;
font-size: 14px;
}
.learn ul {
padding: 0;
margin: 0 0 30px 25px;
}
.learn li {
line-height: 20px;
}
.learn p {
font-size: 15px;
font-weight: 300;
line-height: 1.3;
margin-top: 0;
margin-bottom: 0;
}
#issue-count {
display: none;
}
.quote {
border: none;
margin: 20px 0 60px 0;
}
.quote p {
font-style: italic;
}
.quote p:before {
content: '“';
font-size: 50px;
opacity: .15;
position: absolute;
top: -20px;
left: 3px;
}
.quote p:after {
content: '”';
font-size: 50px;
opacity: .15;
position: absolute;
bottom: -42px;
right: 3px;
}
.quote footer {
position: absolute;
bottom: -40px;
right: 0;
}
.quote footer img {
border-radius: 3px;
}
.quote footer a {
margin-left: 5px;
vertical-align: middle;
}
.speech-bubble {
position: relative;
padding: 10px;
background: rgba(0, 0, 0, .04);
border-radius: 5px;
}
.speech-bubble:after {
content: '';
position: absolute;
top: 100%;
right: 30px;
border: 13px solid transparent;
border-top-color: rgba(0, 0, 0, .04);
}
.learn-bar > .learn {
position: absolute;
width: 272px;
top: 8px;
left: -300px;
padding: 10px;
border-radius: 5px;
background-color: rgba(255, 255, 255, .6);
transition-property: left;
transition-duration: 500ms;
}
@media (min-width: 899px) {
.learn-bar {
width: auto;
padding-left: 300px;
}
.learn-bar > .learn {
left: 8px;
}
}
/* global _ */
(function () { (function () {
'use strict'; 'use strict';
/* jshint ignore:start */
// Underscore's Template Module // Underscore's Template Module
// Courtesy of underscorejs.org // Courtesy of underscorejs.org
var _ = (function (_) { var _ = (function (_) {
...@@ -114,6 +116,7 @@ ...@@ -114,6 +116,7 @@
if (location.hostname === 'todomvc.com') { 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')); 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'));
} }
/* jshint ignore:end */
function redirect() { function redirect() {
if (location.hostname === 'tastejs.github.io') { if (location.hostname === 'tastejs.github.io') {
...@@ -175,13 +178,17 @@ ...@@ -175,13 +178,17 @@
if (learnJSON.backend) { if (learnJSON.backend) {
this.frameworkJSON = learnJSON.backend; this.frameworkJSON = learnJSON.backend;
this.frameworkJSON.issueLabel = framework;
this.append({ this.append({
backend: true backend: true
}); });
} else if (learnJSON[framework]) { } else if (learnJSON[framework]) {
this.frameworkJSON = learnJSON[framework]; this.frameworkJSON = learnJSON[framework];
this.frameworkJSON.issueLabel = framework;
this.append(); this.append();
} }
this.fetchIssueCount();
} }
Learn.prototype.append = function (opts) { Learn.prototype.append = function (opts) {
...@@ -212,6 +219,26 @@ ...@@ -212,6 +219,26 @@
document.body.insertAdjacentHTML('afterBegin', aside.outerHTML); document.body.insertAdjacentHTML('afterBegin', aside.outerHTML);
}; };
Learn.prototype.fetchIssueCount = function () {
var issueLink = document.getElementById('issue-count-link');
if (issueLink) {
var url = issueLink.href.replace('https://github.com', 'https://api.github.com/repos');
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function (e) {
var parsedResponse = JSON.parse(e.target.responseText);
if (parsedResponse instanceof Array) {
var count = parsedResponse.length
if (count !== 0) {
issueLink.innerHTML = 'This app has ' + count + ' open issues';
document.getElementById('issue-count').style.display = 'inline';
}
}
};
xhr.send();
}
};
redirect(); redirect();
getFile('learn.json', Learn); getFile('learn.json', Learn);
})(); })();
{
"private": true,
"dependencies": {
"olives": "^1.6.0",
"emily": "^1.8.1",
"requirejs": "^2.1.5",
"todomvc-common": "^1.0.1",
"todomvc-app-css": "^1.0.1"
}
}
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