From af83a8249e38b45302eb1de44dad5167ace096b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Wed, 17 Apr 2019 15:37:04 +0200 Subject: [PATCH] [REM] examples: remove todoapp It now is available on the playground --- examples/readme.md | 12 -- examples/todoapp/TodoApp.js | 63 ------ examples/todoapp/TodoItem.js | 51 ----- examples/todoapp/app.css | 376 --------------------------------- examples/todoapp/index.html | 16 -- examples/todoapp/main.js | 26 --- examples/todoapp/store.js | 75 ------- examples/todoapp/templates.xml | 56 ----- 8 files changed, 675 deletions(-) delete mode 100644 examples/todoapp/TodoApp.js delete mode 100644 examples/todoapp/TodoItem.js delete mode 100644 examples/todoapp/app.css delete mode 100644 examples/todoapp/index.html delete mode 100644 examples/todoapp/main.js delete mode 100644 examples/todoapp/store.js delete mode 100644 examples/todoapp/templates.xml diff --git a/examples/readme.md b/examples/readme.md index cff43172..814d4112 100644 --- a/examples/readme.md +++ b/examples/readme.md @@ -3,7 +3,6 @@ This project features three example to illustrate how to work with the web-core framework: - _benchmarks_ is a small application to test large number of widgets, -- _todoapp_ is the classical todo application (from the todomvc project), ## Benchmarks @@ -19,14 +18,3 @@ be used to alter the number of visible widgets. Note that each message is itself a widget, with a sub widget. This example could be made faster (by not using subwidgets), but the point is to observe/measure the overhead of the Component class. - -## Todo App - -The Todo App is the classical todo application from _http://todomvc.com/_. It is a good mini application with non trivial data structures and interface updates. - -``` -npm run example:todoapp:build # make a build in dist/examples/ -npm run example:todoapp:dev # make a build in dist/examples/, and make a live server to access it -``` - -It is implemented with the Store class (as in redux/vuex). diff --git a/examples/todoapp/TodoApp.js b/examples/todoapp/TodoApp.js deleted file mode 100644 index af85cc97..00000000 --- a/examples/todoapp/TodoApp.js +++ /dev/null @@ -1,63 +0,0 @@ -import { TodoItem } from "./TodoItem.js"; - -const { Component, connect } = owl; - -const ENTER_KEY = 13; - -function mapStateToProps(state) { - return { todos: state.todos }; -} - -class TodoApp extends Component { - template = "todoapp"; - widgets = { TodoItem }; - state = { filter: "all" }; - - get visibleTodos() { - let todos = this.props.todos; - if (this.state.filter === "active") { - todos = todos.filter(t => !t.completed); - } - if (this.state.filter === "completed") { - todos = todos.filter(t => t.completed); - } - return todos; - } - - get allChecked() { - return this.props.todos.every(todo => todo.completed); - } - - get remaining() { - return this.props.todos.filter(todo => !todo.completed).length; - } - - get remainingText() { - const items = this.remaining < 2 ? "item" : "items"; - return ` ${items} left`; - } - - addTodo(ev) { - if (ev.keyCode === ENTER_KEY) { - const title = ev.target.value; - if (title.trim()) { - this.env.store.dispatch("addTodo", title); - } - ev.target.value = ""; - } - } - - clearCompleted() { - this.env.store.dispatch("clearCompleted"); - } - - toggleAll() { - this.env.store.dispatch("toggleAll", !this.allChecked); - } - - setFilter(filter) { - this.state.filter = filter; - } -} - -export default connect(mapStateToProps)(TodoApp); diff --git a/examples/todoapp/TodoItem.js b/examples/todoapp/TodoItem.js deleted file mode 100644 index 5bb3f1ed..00000000 --- a/examples/todoapp/TodoItem.js +++ /dev/null @@ -1,51 +0,0 @@ -const ENTER_KEY = 13; -const ESC_KEY = 27; - -export class TodoItem extends owl.Component { - template = "todoitem"; - - state = { isEditing: false }; - - removeTodo() { - this.env.store.dispatch("removeTodo", this.props.id); - } - - toggleTodo() { - this.env.store.dispatch("toggleTodo", this.props.id); - } - - async editTodo() { - this.state.isEditing = true; - setTimeout(() => { - this.refs.input.value = ""; - this.refs.input.focus(); - this.refs.input.value = this.props.title; - }); - } - - handleKeyup(ev) { - if (ev.keyCode === ENTER_KEY) { - this.updateTitle(ev.target.value); - } - if (ev.keyCode === ESC_KEY) { - ev.target.value = this.props.title; - this.state.isEditing = false; - } - } - - handleBlur(ev) { - this.updateTitle(ev.target.value); - } - updateTitle(title) { - const value = title.trim(); - if (!value) { - this.removeTodo(this.props.id); - } else { - this.env.store.dispatch("editTodo", { - id: this.props.id, - title: value - }); - this.state.isEditing = false; - } - } -} diff --git a/examples/todoapp/app.css b/examples/todoapp/app.css deleted file mode 100644 index 4dcc858c..00000000 --- a/examples/todoapp/app.css +++ /dev/null @@ -1,376 +0,0 @@ -html, -body { - margin: 0; - padding: 0; -} - -button { - margin: 0; - padding: 0; - border: 0; - background: none; - font-size: 100%; - vertical-align: baseline; - font-family: inherit; - font-weight: inherit; - color: inherit; - -webkit-appearance: none; - appearance: none; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -body { - font: 14px "Helvetica Neue", Helvetica, Arial, sans-serif; - line-height: 1.4em; - background: #f5f5f5; - color: #4d4d4d; - min-width: 230px; - max-width: 550px; - margin: 0 auto; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - font-weight: 300; -} - -:focus { - outline: 0; -} - -.hidden { - display: none; -} - -.todoapp { - background: #fff; - margin: 130px 0 40px 0; - position: relative; - 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; - font-weight: 300; - color: #e6e6e6; -} - -.todoapp input::input-placeholder { - font-style: italic; - font-weight: 300; - color: #e6e6e6; -} - -.todoapp h1 { - position: absolute; - top: -155px; - width: 100%; - font-size: 100px; - font-weight: 100; - text-align: center; - color: rgba(175, 47, 47, 0.15); - -webkit-text-rendering: optimizeLegibility; - -moz-text-rendering: optimizeLegibility; - text-rendering: optimizeLegibility; -} - -.new-todo, -.edit { - position: relative; - margin: 0; - width: 100%; - font-size: 24px; - font-family: inherit; - font-weight: inherit; - line-height: 1.4em; - border: 0; - color: inherit; - padding: 6px; - border: 1px solid #999; - box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2); - box-sizing: border-box; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.new-todo { - padding: 16px 16px 16px 60px; - border: 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 solid #e6e6e6; -} - -.toggle-all { - width: 1px; - height: 1px; - border: none; /* Mobile Safari */ - opacity: 0; - position: absolute; - right: 100%; - bottom: 100%; -} - -.toggle-all + label { - width: 60px; - height: 34px; - font-size: 0; - position: absolute; - top: -52px; - left: -13px; - -webkit-transform: rotate(90deg); - transform: rotate(90deg); -} - -.toggle-all + label:before { - content: "❯"; - font-size: 22px; - color: #e6e6e6; - padding: 10px 27px 10px 27px; -} - -.toggle-all:checked + label:before { - color: #737373; -} - -.todo-list { - margin: 0; - padding: 0; - list-style: none; -} - -.todo-list li { - position: relative; - font-size: 24px; - border-bottom: 1px solid #ededed; -} - -.todo-list li:last-child { - border-bottom: none; -} - -.todo-list li.editing { - border-bottom: none; - padding: 0; -} - -.todo-list li.editing .edit { - display: block; - width: calc(100% - 43px); - padding: 12px 16px; - margin: 0 0 0 43px; -} - -.todo-list li.editing .view { - display: none; -} - -.todo-list li .toggle { - text-align: center; - width: 40px; - /* auto, since non-WebKit browsers doesn't support input styling */ - height: auto; - position: absolute; - top: 0; - bottom: 0; - margin: auto 0; - border: none; /* Mobile Safari */ - -webkit-appearance: none; - appearance: none; -} - -.todo-list li .toggle { - opacity: 0; -} - -.todo-list li .toggle + label { - /* - Firefox requires `#` to be escaped - https://bugzilla.mozilla.org/show_bug.cgi?id=922433 - IE and Edge requires *everything* to be escaped to render, so we do that instead of just the `#` - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7157459/ - */ - background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E"); - background-repeat: no-repeat; - background-position: center left; -} - -.todo-list li .toggle:checked + label { - background-image: url("data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E"); -} - -.todo-list li label { - word-break: break-all; - padding: 15px 15px 15px 60px; - display: block; - line-height: 1.2; - transition: color 0.4s; -} - -.todo-list li.completed label { - color: #d9d9d9; - text-decoration: line-through; -} - -.todo-list li .destroy { - display: none; - position: absolute; - top: 0; - right: 10px; - bottom: 0; - width: 40px; - height: 40px; - margin: auto 0; - font-size: 30px; - color: #cc9a9a; - margin-bottom: 11px; - transition: color 0.2s ease-out; -} - -.todo-list li .destroy:hover { - color: #af5b5e; -} - -.todo-list li .destroy:after { - content: "×"; -} - -.todo-list li:hover .destroy { - display: block; -} - -.todo-list li .edit { - display: none; -} - -.todo-list li.editing:last-child { - margin-bottom: -1px; -} - -.footer { - color: #777; - padding: 10px 15px; - height: 20px; - text-align: center; - border-top: 1px solid #e6e6e6; -} - -.footer:before { - content: ""; - position: absolute; - right: 0; - bottom: 0; - left: 0; - height: 50px; - 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 { - float: left; - text-align: left; -} - -.todo-count strong { - font-weight: 300; -} - -.filters { - margin: 0; - padding: 0; - list-style: none; - position: absolute; - right: 0; - left: 0; -} - -.filters li { - display: inline; -} - -.filters li a { - color: inherit; - margin: 3px; - padding: 3px 7px; - text-decoration: none; - border: 1px solid transparent; - border-radius: 3px; -} - -.filters li a:hover { - border-color: rgba(175, 47, 47, 0.1); -} - -.filters li a.selected { - border-color: rgba(175, 47, 47, 0.2); -} - -.clear-completed, -html .clear-completed:active { - float: right; - position: relative; - line-height: 20px; - text-decoration: none; - cursor: pointer; -} - -.clear-completed:hover { - text-decoration: underline; -} - -.info { - margin: 65px auto 0; - 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 -*/ -@media screen and (-webkit-min-device-pixel-ratio: 0) { - .toggle-all, - .todo-list li .toggle { - background: none; - } - - .todo-list li .toggle { - height: 40px; - } -} - -@media (max-width: 430px) { - .footer { - height: 50px; - } - - .filters { - bottom: 10px; - } -} diff --git a/examples/todoapp/index.html b/examples/todoapp/index.html deleted file mode 100644 index 0ae4af71..00000000 --- a/examples/todoapp/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - Odoo Demo App - - - - - - - - - - - \ No newline at end of file diff --git a/examples/todoapp/main.js b/examples/todoapp/main.js deleted file mode 100644 index c5947e06..00000000 --- a/examples/todoapp/main.js +++ /dev/null @@ -1,26 +0,0 @@ -import TodoApp from "./TodoApp.js"; -import { makeStore } from "./store.js"; - -async function makeEnv() { - const result = await fetch("templates.xml"); - if (!result.ok) { - throw new Error("Error while fetching xml templates"); - } - let templates = await result.text(); - templates = templates.replace(//g, ""); - const qweb = new owl.QWeb(); - qweb.loadTemplates(templates); - return { - qweb, - store: makeStore() - }; -} - -document.addEventListener("DOMContentLoaded", async function() { - const env = await makeEnv(); - const app = new TodoApp(env); - - // for debugging purpose - window.app = app; - await app.mount(document.body); -}); diff --git a/examples/todoapp/store.js b/examples/todoapp/store.js deleted file mode 100644 index 1ce6d897..00000000 --- a/examples/todoapp/store.js +++ /dev/null @@ -1,75 +0,0 @@ -//------------------------------------------------------------------------------ -// ACTIONS -//------------------------------------------------------------------------------ - -const actions = { - addTodo({ commit }, title) { - commit("addTodo", title); - }, - removeTodo({ commit }, id) { - commit("removeTodo", id); - }, - toggleTodo({ state, commit }, id) { - const todo = state.todos.find(t => t.id === id); - commit("editTodo", { id, completed: !todo.completed }); - }, - clearCompleted({ state, commit }) { - state.todos - .filter(todo => todo.completed) - .forEach(todo => { - commit("removeTodo", todo.id); - }); - }, - toggleAll({ state, commit }, completed) { - state.todos.forEach(todo => { - commit("editTodo", { id: todo.id, completed }); - }); - }, - editTodo({ commit }, { id, title }) { - commit("editTodo", { id, title }); - } -}; - -//------------------------------------------------------------------------------ -// MUTATIONS -//------------------------------------------------------------------------------ - -const mutations = { - addTodo({ state }, title) { - const id = state.nextId++; - const todo = { id, title, completed: false }; - state.todos.push(todo); - }, - removeTodo({ state }, id) { - const index = state.todos.findIndex(t => t.id === id); - state.todos.splice(index, 1); - }, - editTodo({ state }, { id, title, completed }) { - const todo = state.todos.find(t => t.id === id); - if (title !== undefined) { - todo.title = title; - } - if (completed !== undefined) { - todo.completed = completed; - } - } -}; - -//------------------------------------------------------------------------------ -// STORE -//------------------------------------------------------------------------------ -const LOCALSTORAGE_KEY = "todos-odoo"; - -export function makeStore() { - const todos = JSON.parse( - window.localStorage.getItem(LOCALSTORAGE_KEY) || "[]" - ); - const nextId = Math.max(0, ...todos.map(t => t.id || 0)) + 1; - const state = { todos, nextId }; - const store = new owl.Store({ state, actions, mutations }); - store.on("update", null, () => { - const state = JSON.stringify(store.state.todos); - window.localStorage.setItem(LOCALSTORAGE_KEY, state); - }); - return store; -} diff --git a/examples/todoapp/templates.xml b/examples/todoapp/templates.xml deleted file mode 100644 index d43a4541..00000000 --- a/examples/todoapp/templates.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - -
- -
-

todos

- -
- -
- - -
    - - - -
-
- - -
- -
  • -
    - - - -
    - -
  • - -