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 @@
<head>
<meta charset="utf-8">
<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">
</head>
<body>
......@@ -38,10 +39,10 @@
<p>Created by <a href="http://github.com/podefr">Olivier Scherrer</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>
<script src="bower_components/todomvc-common/base.js"></script>
<script src="bower_components/requirejs/require.js"></script>
<script src="bower_components/emily/build/Emily.js"></script>
<script src="bower_components/olives/build/Olives.js"></script>
<script src="node_modules/todomvc-common/base.js"></script>
<script src="node_modules/requirejs/require.js"></script>
<script src="node_modules/emily/build/Emily.js"></script>
<script src="node_modules/olives/build/Olives.js"></script>
<script src="js/lib/Tools.js"></script>
<script src="js/uis/Input.js"></script>
<script src="js/uis/List.js"></script>
......
......@@ -7,7 +7,7 @@
'Todos/Input',
'Todos/List',
'Todos/Controls',
'bower_components/olives/src/LocalStore',
'node_modules/olives/build/src/LocalStore',
'Store'
],
......
......@@ -3,9 +3,9 @@
'use strict';
define('Todos/Controls', [
'bower_components/olives/src/OObject',
'bower_components/olives/src/Event.plugin',
'bower_components/olives/src/Bind.plugin',
'node_modules/olives/build/src/OObject',
'node_modules/olives/build/src/Event.plugin',
'node_modules/olives/build/src/Bind.plugin',
'LocalStore',
'Todos/Tools'
],
......
......@@ -5,8 +5,8 @@
// It's going to be called Input
define('Todos/Input', [
// It uses the Olives' OObject and the Event Plugin to listen to dom events and connect them to methods
'bower_components/olives/src/OObject',
'bower_components/olives/src/Event.plugin'
'node_modules/olives/build/src/OObject',
'node_modules/olives/build/src/Event.plugin'
],
// The Input UI
......
......@@ -3,9 +3,9 @@
'use strict';
define('Todos/List', [
'bower_components/olives/src/OObject',
'bower_components/olives/src/Event.plugin',
'bower_components/olives/src/Bind.plugin',
'node_modules/olives/build/src/OObject',
'node_modules/olives/build/src/Event.plugin',
'node_modules/olives/build/src/Bind.plugin',
'Todos/Tools'
],
......
/** 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.
* 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.15',
version = '2.1.16',
commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg,
cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,
jsSuffixRegExp = /\.js$/,
......@@ -1123,6 +1123,13 @@ var requirejs, require, define;
if (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,25 +12,30 @@ button {
font-size: 100%;
vertical-align: baseline;
font-family: inherit;
font-weight: inherit;
color: inherit;
-webkit-appearance: none;
-ms-appearance: none;
-o-appearance: none;
appearance: none;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
font-smoothing: antialiased;
}
body {
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
line-height: 1.4em;
background: #eaeaea url('bg.png');
background: #f5f5f5;
color: #4d4d4d;
width: 550px;
min-width: 230px;
max-width: 550px;
margin: 0 auto;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased;
font-weight: 300;
}
button,
......@@ -38,78 +43,50 @@ input[type="checkbox"] {
outline: none;
}
.hidden {
display: none;
}
#todoapp {
background: #fff;
background: rgba(255, 255, 255, 0.9);
margin: 130px 0 40px 0;
border: 1px solid #ccc;
position: relative;
border-top-left-radius: 2px;
border-top-right-radius: 2px;
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%;
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2),
0 25px 50px 0 rgba(0, 0, 0, 0.1);
}
#todoapp input::-webkit-input-placeholder {
font-style: italic;
font-weight: 300;
color: #e6e6e6;
}
#todoapp input::-moz-placeholder {
font-style: italic;
color: #a9a9a9;
font-weight: 300;
color: #e6e6e6;
}
#todoapp input::input-placeholder {
font-style: italic;
font-weight: 300;
color: #e6e6e6;
}
#todoapp h1 {
position: absolute;
top: -120px;
top: -155px;
width: 100%;
font-size: 70px;
font-weight: bold;
font-size: 100px;
font-weight: 100;
text-align: center;
color: #b3b3b3;
color: rgba(255, 255, 255, 0.3);
text-shadow: -1px -1px rgba(0, 0, 0, 0.2);
color: rgba(175, 47, 47, 0.15);
-webkit-text-rendering: optimizeLegibility;
-moz-text-rendering: optimizeLegibility;
-ms-text-rendering: optimizeLegibility;
-o-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,
.edit {
position: relative;
......@@ -117,6 +94,7 @@ input[type="checkbox"] {
width: 100%;
font-size: 24px;
font-family: inherit;
font-weight: inherit;
line-height: 1.4em;
border: 0;
outline: none;
......@@ -124,29 +102,25 @@ input[type="checkbox"] {
padding: 6px;
border: 1px solid #999;
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased;
}
#new-todo {
padding: 16px 16px 16px 60px;
border: none;
background: rgba(0, 0, 0, 0.02);
z-index: 2;
box-shadow: none;
background: rgba(0, 0, 0, 0.003);
box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03);
}
#main {
position: relative;
z-index: 2;
border-top: 1px dotted #adadad;
border-top: 1px solid #e6e6e6;
}
label[for='toggle-all'] {
......@@ -155,19 +129,19 @@ label[for='toggle-all'] {
#toggle-all {
position: absolute;
top: -42px;
left: -4px;
width: 40px;
top: -55px;
left: -12px;
width: 60px;
height: 34px;
text-align: center;
/* Mobile Safari */
border: none;
border: none; /* Mobile Safari */
}
#toggle-all:before {
content: '»';
font-size: 28px;
color: #d9d9d9;
padding: 0 25px 7px;
content: '';
font-size: 22px;
color: #e6e6e6;
padding: 10px 27px 10px 27px;
}
#toggle-all:checked:before {
......@@ -183,7 +157,7 @@ label[for='toggle-all'] {
#todo-list li {
position: relative;
font-size: 24px;
border-bottom: 1px dotted #ccc;
border-bottom: 1px solid #ededed;
}
#todo-list li:last-child {
......@@ -215,28 +189,18 @@ label[for='toggle-all'] {
top: 0;
bottom: 0;
margin: auto 0;
/* Mobile Safari */
border: none;
border: none; /* Mobile Safari */
-webkit-appearance: none;
-ms-appearance: none;
-o-appearance: none;
appearance: none;
}
#todo-list li .toggle:after {
content: '✔';
/* 40 + a couple of pixels visual adjustment */
line-height: 43px;
font-size: 20px;
color: #d9d9d9;
text-shadow: 0 -1px 0 #bfbfbf;
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>');
}
#todo-list li .toggle:checked:after {
color: #85ada7;
text-shadow: 0 1px 0 #669991;
bottom: 1px;
position: relative;
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>');
}
#todo-list li label {
......@@ -246,12 +210,11 @@ label[for='toggle-all'] {
margin-left: 45px;
display: block;
line-height: 1.2;
-webkit-transition: color 0.4s;
transition: color 0.4s;
}
#todo-list li.completed label {
color: #a9a9a9;
color: #d9d9d9;
text-decoration: line-through;
}
......@@ -264,21 +227,18 @@ label[for='toggle-all'] {
width: 40px;
height: 40px;
margin: auto 0;
font-size: 22px;
color: #a88a8a;
-webkit-transition: all 0.2s;
transition: all 0.2s;
font-size: 30px;
color: #cc9a9a;
margin-bottom: 11px;
transition: color 0.2s ease-out;
}
#todo-list li .destroy:hover {
text-shadow: 0 0 1px #000,
0 0 10px rgba(199, 107, 107, 0.8);
-webkit-transform: scale(1.3);
transform: scale(1.3);
color: #af5b5e;
}
#todo-list li .destroy:after {
content: '';
content: '×';
}
#todo-list li:hover .destroy {
......@@ -295,29 +255,25 @@ label[for='toggle-all'] {
#footer {
color: #777;
padding: 0 15px;
position: absolute;
right: 0;
bottom: -31px;
left: 0;
padding: 10px 15px;
height: 20px;
z-index: 1;
text-align: center;
border-top: 1px solid #e6e6e6;
}
#footer:before {
content: '';
position: absolute;
right: 0;
bottom: 31px;
bottom: 0;
left: 0;
height: 50px;
z-index: -1;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3),
0 6px 0 -3px rgba(255, 255, 255, 0.8),
0 7px 1px -3px rgba(0, 0, 0, 0.3),
0 43px 0 -6px rgba(255, 255, 255, 0.8),
0 44px 2px -6px rgba(0, 0, 0, 0.2);
overflow: hidden;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2),
0 8px 0 -3px #f6f6f6,
0 9px 1px -3px rgba(0, 0, 0, 0.2),
0 16px 0 -6px #f6f6f6,
0 17px 2px -6px rgba(0, 0, 0, 0.2);
}
#todo-count {
......@@ -325,6 +281,10 @@ label[for='toggle-all'] {
text-align: left;
}
#todo-count strong {
font-weight: 300;
}
#filters {
margin: 0;
padding: 0;
......@@ -339,49 +299,73 @@ label[for='toggle-all'] {
}
#filters li a {
color: #83756f;
margin: 2px;
color: inherit;
margin: 3px;
padding: 3px 7px;
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 {
font-weight: bold;
border-color: rgba(175, 47, 47, 0.2);
}
#clear-completed {
#clear-completed,
html #clear-completed:active {
float: right;
position: relative;
line-height: 20px;
text-decoration: none;
background: rgba(0, 0, 0, 0.1);
font-size: 11px;
padding: 0 10px;
border-radius: 3px;
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
cursor: pointer;
visibility: hidden;
position: relative;
}
#clear-completed::after {
visibility: visible;
content: 'Clear completed';
position: absolute;
top: 0;
right: 0;
white-space: nowrap;
}
#clear-completed:hover {
background: rgba(0, 0, 0, 0.15);
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3);
#clear-completed:hover::after {
text-decoration: underline;
}
#info {
margin: 65px auto 0;
color: #a6a6a6;
font-size: 12px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
color: #bfbfbf;
font-size: 10px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
text-align: center;
}
#info p {
line-height: 1;
}
#info a {
color: inherit;
text-decoration: none;
font-weight: 400;
}
#info a:hover {
text-decoration: underline;
}
/*
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) {
#toggle-all,
#todo-list li .toggle {
......@@ -393,10 +377,6 @@ label[for='toggle-all'] {
}
#toggle-all {
top: -56px;
left: -15px;
width: 65px;
height: 41px;
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
-webkit-appearance: none;
......@@ -404,151 +384,12 @@ label[for='toggle-all'] {
}
}
.hidden {
display: none;
}
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;
@media (max-width: 430px) {
#footer {
height: 50px;
}
.learn-bar #todoapp {
width: 550px;
margin: 130px auto 40px auto;
#filters {
bottom: 10px;
}
}
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 () {
'use strict';
/* jshint ignore:start */
// Underscore's Template Module
// Courtesy of underscorejs.org
var _ = (function (_) {
......@@ -114,6 +116,7 @@
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'));
}
/* jshint ignore:end */
function redirect() {
if (location.hostname === 'tastejs.github.io') {
......@@ -175,13 +178,17 @@
if (learnJSON.backend) {
this.frameworkJSON = learnJSON.backend;
this.frameworkJSON.issueLabel = framework;
this.append({
backend: true
});
} else if (learnJSON[framework]) {
this.frameworkJSON = learnJSON[framework];
this.frameworkJSON.issueLabel = framework;
this.append();
}
this.fetchIssueCount();
}
Learn.prototype.append = function (opts) {
......@@ -212,6 +219,26 @@
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();
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