mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
+306
-297
@@ -1,17 +1,17 @@
|
|||||||
const CLICK_COUNTER = `class ClickCounter extends owl.Component {
|
const CLICK_COUNTER = `class ClickCounter extends owl.Component {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(...arguments);
|
super(...arguments);
|
||||||
this.template = "clickcounter";
|
this.template = "clickcounter";
|
||||||
this.state = {value: 0};
|
this.state = { value: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
increment() {
|
increment() {
|
||||||
this.state.value++;
|
this.state.value++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const qweb = new owl.QWeb(TEMPLATES);
|
const qweb = new owl.QWeb(TEMPLATES);
|
||||||
const counter = new ClickCounter({qweb});
|
const counter = new ClickCounter({ qweb });
|
||||||
counter.mount(document.body);
|
counter.mount(document.body);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -29,50 +29,50 @@ const CLICK_COUNTER_CSS = `button {
|
|||||||
|
|
||||||
const CLICK_COUNTER_ESNEXT = `// This example will not work if your browser does not support ESNext class fields
|
const CLICK_COUNTER_ESNEXT = `// This example will not work if your browser does not support ESNext class fields
|
||||||
class ClickCounter extends owl.Component {
|
class ClickCounter extends owl.Component {
|
||||||
template = "clickcounter";
|
template = "clickcounter";
|
||||||
state = {value: 0};
|
state = { value: 0 };
|
||||||
|
|
||||||
increment() {
|
increment() {
|
||||||
this.state.value++;
|
this.state.value++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const qweb = new owl.QWeb(TEMPLATES);
|
const qweb = new owl.QWeb(TEMPLATES);
|
||||||
const counter = new ClickCounter({qweb});
|
const counter = new ClickCounter({ qweb });
|
||||||
counter.mount(document.body);
|
counter.mount(document.body);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const WIDGET_COMPOSITION = `class ClickCounter extends owl.Component {
|
const WIDGET_COMPOSITION = `class ClickCounter extends owl.Component {
|
||||||
constructor(parent, props) {
|
constructor(parent, props) {
|
||||||
super(parent, props);
|
super(parent, props);
|
||||||
this.template = "clickcounter";
|
this.template = "clickcounter";
|
||||||
this.state = {value: props.initialState || 0};
|
this.state = { value: props.initialState || 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
increment() {
|
increment() {
|
||||||
this.state.value++;
|
this.state.value++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let nextId = 1;
|
let nextId = 1;
|
||||||
|
|
||||||
class App extends owl.Component {
|
class App extends owl.Component {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(...arguments);
|
super(...arguments);
|
||||||
this.template = "app";
|
this.template = "app";
|
||||||
this.state = {counters: []}
|
this.state = { counters: [] }
|
||||||
this.widgets = { ClickCounter };
|
this.widgets = { ClickCounter };
|
||||||
}
|
}
|
||||||
|
|
||||||
addCounter() {
|
addCounter() {
|
||||||
this.state.counters.push(nextId++);
|
this.state.counters.push(nextId++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const qweb = new owl.QWeb(TEMPLATES);
|
const qweb = new owl.QWeb(TEMPLATES);
|
||||||
const app = new App({qweb});
|
const app = new App({ qweb });
|
||||||
app.mount(document.body);`;
|
app.mount(document.body);
|
||||||
|
`;
|
||||||
|
|
||||||
const WIDGET_COMPOSITION_XML = `<templates>
|
const WIDGET_COMPOSITION_XML = `<templates>
|
||||||
<button t-name="clickcounter" t-on-click="increment">
|
<button t-name="clickcounter" t-on-click="increment">
|
||||||
@@ -95,54 +95,52 @@ const WIDGET_COMPOSITION_CSS = `button {
|
|||||||
width: 220px;
|
width: 220px;
|
||||||
}`;
|
}`;
|
||||||
|
|
||||||
const LIFECYCLE_DEMO = `const { Component, QWeb } = owl;
|
const LIFECYCLE_DEMO = `class HookWidget extends owl.Component {
|
||||||
|
constructor() {
|
||||||
class HookWidget extends Component {
|
super(...arguments);
|
||||||
constructor() {
|
this.template = "demo.hookwidget";
|
||||||
super(...arguments);
|
this.state = { n: 0 };
|
||||||
this.template = "demo.hookwidget";
|
console.log("constructor");
|
||||||
this.state = { n: 0 };
|
}
|
||||||
console.log("constructor");
|
async willStart() {
|
||||||
}
|
console.log("willstart");
|
||||||
async willStart() {
|
}
|
||||||
console.log("willstart");
|
mounted() {
|
||||||
}
|
console.log("mounted");
|
||||||
mounted() {
|
}
|
||||||
console.log("mounted");
|
async willUpdateProps(nextProps) {
|
||||||
}
|
console.log("willUpdateProps", nextProps);
|
||||||
async willUpdateProps(nextProps) {
|
}
|
||||||
console.log("willUpdateProps", nextProps);
|
willPatch() {
|
||||||
}
|
console.log("willPatch");
|
||||||
willPatch() {
|
}
|
||||||
console.log("willPatch");
|
patched() {
|
||||||
}
|
console.log("patched");
|
||||||
patched() {
|
}
|
||||||
console.log("patched");
|
willUnmount() {
|
||||||
}
|
console.log("willUnmount");
|
||||||
willUnmount() {
|
}
|
||||||
console.log("willUnmount");
|
increment() {
|
||||||
}
|
this.state.n++;
|
||||||
increment() {
|
}
|
||||||
this.state.n++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ParentWidget extends Component {
|
class ParentWidget extends owl.Component {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(...arguments);
|
super(...arguments);
|
||||||
this.widgets = { HookWidget };
|
this.widgets = { HookWidget };
|
||||||
this.template = "demo.parentwidget";
|
this.template = "demo.parentwidget";
|
||||||
this.state = { n: 0, flag: true };
|
this.state = { n: 0, flag: true };
|
||||||
}
|
}
|
||||||
increment() {
|
increment() {
|
||||||
this.state.n++;
|
this.state.n++;
|
||||||
}
|
}
|
||||||
toggleSubWidget() {
|
toggleSubWidget() {
|
||||||
this.state.flag = !this.state.flag;
|
this.state.flag = !this.state.flag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const qweb = new QWeb(TEMPLATES);
|
const qweb = new owl.QWeb(TEMPLATES);
|
||||||
const widget = new ParentWidget({ qweb });
|
const widget = new ParentWidget({ qweb });
|
||||||
widget.mount(document.body);
|
widget.mount(document.body);
|
||||||
`;
|
`;
|
||||||
@@ -164,92 +162,88 @@ const BENCHMARK_APP = `//-------------------------------------------------------
|
|||||||
const messages = [];
|
const messages = [];
|
||||||
const authors = ["Aaron", "David", "Vincent"];
|
const authors = ["Aaron", "David", "Vincent"];
|
||||||
const content = [
|
const content = [
|
||||||
"Lorem ipsum dolor sit amet",
|
"Lorem ipsum dolor sit amet",
|
||||||
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem",
|
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem",
|
||||||
"Excepteur sint occaecat cupidatat non proident"
|
"Excepteur sint occaecat cupidatat non proident"
|
||||||
];
|
];
|
||||||
|
|
||||||
function chooseRandomly(array) {
|
function chooseRandomly(array) {
|
||||||
const index = Math.floor(Math.random() * array.length);
|
const index = Math.floor(Math.random() * array.length);
|
||||||
return array[index];
|
return array[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 1; i < 16000; i++) {
|
for (let i = 1; i < 16000; i++) {
|
||||||
messages.push({
|
messages.push({
|
||||||
id: i,
|
id: i,
|
||||||
author: chooseRandomly(authors),
|
author: chooseRandomly(authors),
|
||||||
msg: \`\${i}: \${chooseRandomly(content)}\`,
|
msg: \`\${i}: \${chooseRandomly(content)}\`,
|
||||||
likes: 0
|
likes: 0
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Counter Widget
|
// Counter Widget
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
class Counter extends owl.Component {
|
class Counter extends owl.Component {
|
||||||
constructor(parent, props) {
|
constructor(parent, props) {
|
||||||
super(parent, props);
|
super(parent, props);
|
||||||
this.template = "counter";
|
this.template = "counter";
|
||||||
this.state = {
|
this.state = { counter: props.initialState || 0 };
|
||||||
counter: props.initialState || 0
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
increment(delta) {
|
increment(delta) {
|
||||||
this.state.counter += delta;
|
this.state.counter += delta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Message Widget
|
// Message Widget
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
class Message extends owl.Component {
|
class Message extends owl.Component {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(...arguments);
|
super(...arguments);
|
||||||
this.template = "message";
|
this.template = "message";
|
||||||
this.widgets = { Counter };
|
this.widgets = { Counter };
|
||||||
}
|
}
|
||||||
|
|
||||||
removeMessage() {
|
removeMessage() {
|
||||||
this.trigger("remove_message", {
|
this.trigger("remove_message", {
|
||||||
id: this.props.id
|
id: this.props.id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Root Widget
|
// Root Widget
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
class App extends owl.Component {
|
class App extends owl.Component {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(...arguments);
|
super(...arguments);
|
||||||
this.template = "root";
|
this.template = "root";
|
||||||
this.widgets = { Message };
|
this.widgets = { Message };
|
||||||
this.state = {
|
this.state = { messages: messages.slice(0, 10) };
|
||||||
messages: messages.slice(0, 10)
|
}
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
setMessageCount(n) {
|
setMessageCount(n) {
|
||||||
this.state.messages = messages.slice(0,n);
|
this.state.messages = messages.slice(0, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeMessage(data) {
|
removeMessage(data) {
|
||||||
const index = messages.findIndex(m => m.id === data.id);
|
const index = messages.findIndex(m => m.id === data.id);
|
||||||
this.state.messages.splice(index, 1);
|
this.state.messages.splice(index, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
increment(delta) {
|
increment(delta) {
|
||||||
const n = this.state.messages.length + delta;
|
const n = this.state.messages.length + delta;
|
||||||
this.setMessageCount(n);
|
this.setMessageCount(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Application initialization
|
// Application initialization
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
const env = {
|
const env = {
|
||||||
qweb: new owl.QWeb(TEMPLATES)
|
qweb: new owl.QWeb(TEMPLATES)
|
||||||
};
|
};
|
||||||
|
|
||||||
const app = new App(env);
|
const app = new App(env);
|
||||||
@@ -349,177 +343,193 @@ const LOCALSTORAGE_KEY = "todos-odoo";
|
|||||||
// Store Definition
|
// Store Definition
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
const actions = {
|
const actions = {
|
||||||
addTodo({ commit }, title) {
|
addTodo({ commit }, title) {
|
||||||
commit("addTodo", title);
|
commit("addTodo", title);
|
||||||
},
|
},
|
||||||
removeTodo({ commit }, id) {
|
removeTodo({ commit }, id) {
|
||||||
commit("removeTodo", id);
|
commit("removeTodo", id);
|
||||||
},
|
},
|
||||||
toggleTodo({ state, commit }, id) {
|
toggleTodo({ state, commit }, id) {
|
||||||
const todo = state.todos.find(t => t.id === id);
|
const todo = state.todos.find(t => t.id === id);
|
||||||
commit("editTodo", { id, completed: !todo.completed });
|
commit("editTodo", { id, completed: !todo.completed });
|
||||||
},
|
},
|
||||||
clearCompleted({ state, commit }) {
|
clearCompleted({ state, commit }) {
|
||||||
state.todos
|
state.todos
|
||||||
.filter(todo => todo.completed)
|
.filter(todo => todo.completed)
|
||||||
.forEach(todo => {
|
.forEach(todo => {
|
||||||
commit("removeTodo", todo.id);
|
commit("removeTodo", todo.id);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
toggleAll({ state, commit }, completed) {
|
toggleAll({ state, commit }, completed) {
|
||||||
state.todos.forEach(todo => {
|
state.todos.forEach(todo => {
|
||||||
commit("editTodo", { id: todo.id, completed });
|
commit("editTodo", {
|
||||||
});
|
id: todo.id,
|
||||||
},
|
completed
|
||||||
editTodo({ commit }, { id, title }) {
|
});
|
||||||
commit("editTodo", { id, title });
|
});
|
||||||
}
|
},
|
||||||
|
editTodo({ commit }, { id, title }) {
|
||||||
|
commit("editTodo", { id, title });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const mutations = {
|
const mutations = {
|
||||||
addTodo({ state }, title) {
|
addTodo({ state }, title) {
|
||||||
const id = state.nextId++;
|
const id = state.nextId++;
|
||||||
const todo = { id, title, completed: false };
|
const todo = {
|
||||||
state.todos.push(todo);
|
id,
|
||||||
},
|
title,
|
||||||
removeTodo({ state }, id) {
|
completed: false
|
||||||
const index = state.todos.findIndex(t => t.id === id);
|
};
|
||||||
state.todos.splice(index, 1);
|
state.todos.push(todo);
|
||||||
},
|
},
|
||||||
editTodo({ state }, { id, title, completed }) {
|
removeTodo({ state }, id) {
|
||||||
const todo = state.todos.find(t => t.id === id);
|
const index = state.todos.findIndex(t => t.id === id);
|
||||||
if (title !== undefined) {
|
state.todos.splice(index, 1);
|
||||||
todo.title = title;
|
},
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (completed !== undefined) {
|
|
||||||
todo.completed = completed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function makeStore() {
|
function makeStore() {
|
||||||
const todos = JSON.parse(
|
const todos = JSON.parse(
|
||||||
window.localStorage.getItem(LOCALSTORAGE_KEY) || "[]"
|
window.localStorage.getItem(LOCALSTORAGE_KEY) || "[]"
|
||||||
);
|
);
|
||||||
const nextId = Math.max(0, ...todos.map(t => t.id || 0)) + 1;
|
const nextId = Math.max(0, ...todos.map(t => t.id || 0)) + 1;
|
||||||
const state = { todos, nextId };
|
const state = {
|
||||||
const store = new owl.Store({ state, actions, mutations });
|
todos,
|
||||||
store.on("update", null, () => {
|
nextId
|
||||||
const state = JSON.stringify(store.state.todos);
|
};
|
||||||
window.localStorage.setItem(LOCALSTORAGE_KEY, state);
|
const store = new owl.Store({
|
||||||
});
|
state,
|
||||||
return store;
|
actions,
|
||||||
|
mutations
|
||||||
|
});
|
||||||
|
store.on("update", null, () => {
|
||||||
|
const state = JSON.stringify(store.state.todos);
|
||||||
|
window.localStorage.setItem(LOCALSTORAGE_KEY, state);
|
||||||
|
});
|
||||||
|
return store;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// TodoItem
|
// TodoItem
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
class TodoItem extends owl.Component {
|
class TodoItem extends owl.Component {
|
||||||
template = "todoitem";
|
template = "todoitem";
|
||||||
state = { isEditing: false };
|
state = { isEditing: false };
|
||||||
|
|
||||||
removeTodo() {
|
removeTodo() {
|
||||||
this.env.store.dispatch("removeTodo", this.props.id);
|
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) {
|
toggleTodo() {
|
||||||
this.updateTitle(ev.target.value);
|
this.env.store.dispatch("toggleTodo", this.props.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateTitle(title) {
|
async editTodo() {
|
||||||
const value = title.trim();
|
this.state.isEditing = true;
|
||||||
if (!value) {
|
setTimeout(() => {
|
||||||
this.removeTodo(this.props.id);
|
this.refs.input.value = "";
|
||||||
} else {
|
this.refs.input.focus();
|
||||||
this.env.store.dispatch("editTodo", {
|
this.refs.input.value = this.props.title;
|
||||||
id: this.props.id,
|
});
|
||||||
title: value
|
}
|
||||||
});
|
|
||||||
this.state.isEditing = false;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// TodoApp
|
// TodoApp
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
function mapStateToProps(state) {
|
function mapStateToProps(state) {
|
||||||
return { todos: state.todos };
|
return {
|
||||||
|
todos: state.todos
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class TodoApp extends owl.Component {
|
class TodoApp extends owl.Component {
|
||||||
template = "todoapp";
|
template = "todoapp";
|
||||||
widgets = { TodoItem };
|
widgets = { TodoItem };
|
||||||
state = { filter: "all" };
|
state = { filter: "all" };
|
||||||
|
|
||||||
get visibleTodos() {
|
get visibleTodos() {
|
||||||
let todos = this.props.todos;
|
let todos = this.props.todos;
|
||||||
if (this.state.filter === "active") {
|
if (this.state.filter === "active") {
|
||||||
todos = todos.filter(t => !t.completed);
|
todos = todos.filter(t => !t.completed);
|
||||||
|
}
|
||||||
|
if (this.state.filter === "completed") {
|
||||||
|
todos = todos.filter(t => t.completed);
|
||||||
|
}
|
||||||
|
return todos;
|
||||||
}
|
}
|
||||||
if (this.state.filter === "completed") {
|
|
||||||
todos = todos.filter(t => t.completed);
|
get allChecked() {
|
||||||
|
return this.props.todos.every(todo => todo.completed);
|
||||||
}
|
}
|
||||||
return todos;
|
|
||||||
}
|
|
||||||
|
|
||||||
get allChecked() {
|
get remaining() {
|
||||||
return this.props.todos.every(todo => todo.completed);
|
return this.props.todos.filter(todo => !todo.completed).length;
|
||||||
}
|
|
||||||
|
|
||||||
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() {
|
get remainingText() {
|
||||||
this.env.store.dispatch("clearCompleted");
|
const items = this.remaining < 2 ? "item" : "items";
|
||||||
}
|
return \` \${items} left\`;
|
||||||
|
}
|
||||||
|
|
||||||
toggleAll() {
|
addTodo(ev) {
|
||||||
this.env.store.dispatch("toggleAll", !this.allChecked);
|
if (ev.keyCode === ENTER_KEY) {
|
||||||
}
|
const title = ev.target.value;
|
||||||
|
if (title.trim()) {
|
||||||
|
this.env.store.dispatch("addTodo", title);
|
||||||
|
}
|
||||||
|
ev.target.value = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
setFilter(filter) {
|
clearCompleted() {
|
||||||
this.state.filter = filter;
|
this.env.store.dispatch("clearCompleted");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleAll() {
|
||||||
|
this.env.store.dispatch("toggleAll", !this.allChecked);
|
||||||
|
}
|
||||||
|
|
||||||
|
setFilter(filter) {
|
||||||
|
this.state.filter = filter;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const ConnectedTodoApp = owl.connect(mapStateToProps)(TodoApp);
|
const ConnectedTodoApp = owl.connect(mapStateToProps)(TodoApp);
|
||||||
@@ -530,8 +540,8 @@ const ConnectedTodoApp = owl.connect(mapStateToProps)(TodoApp);
|
|||||||
const store = makeStore();
|
const store = makeStore();
|
||||||
const qweb = new owl.QWeb(TEMPLATES);
|
const qweb = new owl.QWeb(TEMPLATES);
|
||||||
const env = {
|
const env = {
|
||||||
qweb,
|
qweb,
|
||||||
store
|
store
|
||||||
};
|
};
|
||||||
const app = new ConnectedTodoApp(env);
|
const app = new ConnectedTodoApp(env);
|
||||||
app.mount(document.body);
|
app.mount(document.body);
|
||||||
@@ -970,43 +980,43 @@ html .clear-completed:active {
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const RESPONSIVE = `const { Component, QWeb, utils } = owl;
|
const RESPONSIVE = `class SubWidget extends owl.Component {
|
||||||
|
constructor() {
|
||||||
class SubWidget extends Component {
|
super(...arguments);
|
||||||
constructor() {
|
this.template = "subwidget";
|
||||||
super(...arguments);
|
}
|
||||||
this.template = "subwidget";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ResponsiveWidget extends Component {
|
class ResponsiveWidget extends owl.Component {
|
||||||
constructor() {
|
constructor() {
|
||||||
super(...arguments);
|
super(...arguments);
|
||||||
this.template = "responsivewidget";
|
this.template = "responsivewidget";
|
||||||
this.widgets = { SubWidget };
|
this.widgets = { SubWidget };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isMobile() {
|
function isMobile() {
|
||||||
return window.innerWidth <= 768;
|
return window.innerWidth <= 768;
|
||||||
}
|
}
|
||||||
|
|
||||||
const env = {
|
const env = {
|
||||||
qweb: new QWeb(TEMPLATES),
|
qweb: new owl.QWeb(TEMPLATES),
|
||||||
isMobile: isMobile()
|
isMobile: isMobile()
|
||||||
};
|
};
|
||||||
|
|
||||||
const widget = new ResponsiveWidget(env);
|
const widget = new ResponsiveWidget(env);
|
||||||
widget.mount(document.body);
|
widget.mount(document.body);
|
||||||
|
|
||||||
window.addEventListener(
|
window.addEventListener(
|
||||||
"resize",
|
"resize",
|
||||||
utils.debounce(function() {
|
owl.utils.debounce(function() {
|
||||||
const _isMobile = isMobile();
|
const _isMobile = isMobile();
|
||||||
if (_isMobile !== env.isMobile) {
|
if (_isMobile !== env.isMobile) {
|
||||||
widget.updateEnv({ isMobile: _isMobile });
|
widget.updateEnv({
|
||||||
}
|
isMobile: _isMobile
|
||||||
}, 20)
|
});
|
||||||
|
}
|
||||||
|
}, 20)
|
||||||
);
|
);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -1039,13 +1049,12 @@ const RESPONSIVE_CSS = `.info {
|
|||||||
margin: 30px;
|
margin: 30px;
|
||||||
}`;
|
}`;
|
||||||
|
|
||||||
const EMPTY = `const {Component, QWeb} = owl;
|
const EMPTY = `class App extends owl.Component {
|
||||||
class Widget extends Component {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const qweb = new QWeb(TEMPLATES);
|
const qweb = new owl.QWeb(TEMPLATES);
|
||||||
const widget = new Widget({qweb});
|
const app = new App({qweb});
|
||||||
widget.mount(document.body);
|
app.mount(document.body);
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const SAMPLES = [
|
export const SAMPLES = [
|
||||||
|
|||||||
Reference in New Issue
Block a user