├── .babelrc ├── src ├── modules │ ├── store.js │ ├── generateTodo.js │ ├── Todo.js │ ├── updateStatus.js │ ├── TodosContainer.js │ └── UI.js ├── index.html ├── index.js ├── style.css └── todolist.test.js ├── .hintrc ├── webpack.config.js ├── .eslintrc.json ├── .stylelintrc.json ├── LICENSE ├── dist ├── index.html └── main.js ├── package.json ├── .gitignore ├── .github └── workflows │ └── linter.yml └── README.md /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "test": { 4 | "plugins": ["@babel/plugin-transform-modules-commonjs"] 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /src/modules/store.js: -------------------------------------------------------------------------------- 1 | export const getTodos = () => JSON.parse(localStorage.getItem('todos')); 2 | export const setTodos = (obj) => { 3 | localStorage.setItem('todos', JSON.stringify(obj)); 4 | }; -------------------------------------------------------------------------------- /src/modules/generateTodo.js: -------------------------------------------------------------------------------- 1 | import UI from './UI.js'; 2 | 3 | export default function populateTodos(data) { 4 | data.forEach((element) => { 5 | UI.add(element.id, element.description, element.completed); 6 | }); 7 | } -------------------------------------------------------------------------------- /src/modules/Todo.js: -------------------------------------------------------------------------------- 1 | export default class Todo { 2 | constructor(id, description, completed, index) { 3 | this.id = id; 4 | this.description = description; 5 | this.completed = completed; 6 | this.index = index; 7 | } 8 | } -------------------------------------------------------------------------------- /.hintrc: -------------------------------------------------------------------------------- 1 | { 2 | "connector": { 3 | "name": "local", 4 | "options": { 5 | "pattern": ["**", "!.git/**", "!node_modules/**"] 6 | } 7 | }, 8 | "extends": ["development"], 9 | "formatters": ["stylish"], 10 | "hints": [ 11 | "button-type", 12 | "disown-opener", 13 | "html-checker", 14 | "meta-charset-utf-8", 15 | "meta-viewport", 16 | "no-inline-styles:error" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | /* eslint import/no-unresolved:0 */ 2 | const path = require('path'); 3 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 4 | 5 | module.exports = { 6 | module: { 7 | rules: [ 8 | { 9 | test: /\.css$/, 10 | use: ['style-loader', 'css-loader'], 11 | }, 12 | ], 13 | }, 14 | plugins: [ 15 | new HtmlWebpackPlugin({ 16 | template: path.resolve(__dirname, 'src', 'index.html'), 17 | }), 18 | ], 19 | }; -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es6": true, 5 | "jest": true 6 | }, 7 | "parser": "babel-eslint", 8 | "parserOptions": { 9 | "ecmaVersion": 2018, 10 | "sourceType": "module" 11 | }, 12 | "extends": ["airbnb-base"], 13 | "rules": { 14 | "no-shadow": "off", 15 | "no-param-reassign": "off", 16 | "eol-last": "off", 17 | "import/extensions": [ 18 | 1, 19 | { 20 | "js": "always", 21 | "json": "always" 22 | } 23 | ] 24 | }, 25 | "ignorePatterns": ["dist/", "build/"] 26 | } 27 | -------------------------------------------------------------------------------- /src/modules/updateStatus.js: -------------------------------------------------------------------------------- 1 | import { getTodos, setTodos } from './store.js'; 2 | import UI from './UI.js'; 3 | 4 | export const updateStatus = (id) => { 5 | const [statusId] = id.match(/\d+/); 6 | const todos = getTodos().map((todo) => { 7 | if (todo.id === statusId) { 8 | return { ...todo, completed: !todo.completed }; 9 | } 10 | return todo; 11 | }); 12 | setTodos(todos); 13 | UI.updateStatusUI(statusId); 14 | }; 15 | export const clearTodoList = () => { 16 | const listToNotClear = getTodos() 17 | .filter((todo) => todo.completed === false) 18 | .map((todo, index) => ({ ...todo, index: index + 1 })); 19 | const listToClear = getTodos().filter((todo) => todo.completed === true); 20 | 21 | listToClear.forEach((todo) => { 22 | UI.remove(todo.id); 23 | }); 24 | setTodos(listToNotClear); 25 | }; 26 | -------------------------------------------------------------------------------- /.stylelintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["stylelint-config-standard"], 3 | "plugins": ["stylelint-scss", "stylelint-csstree-validator"], 4 | "rules": { 5 | "at-rule-no-unknown": [ 6 | true, 7 | { 8 | "ignoreAtRules": [ 9 | "tailwind", 10 | "apply", 11 | "variants", 12 | "responsive", 13 | "screen" 14 | ] 15 | } 16 | ], 17 | "scss/at-rule-no-unknown": [ 18 | true, 19 | { 20 | "ignoreAtRules": [ 21 | "tailwind", 22 | "apply", 23 | "variants", 24 | "responsive", 25 | "screen" 26 | ] 27 | } 28 | ], 29 | "csstree/validator": true 30 | }, 31 | "ignoreFiles": [ 32 | "build/**", 33 | "dist/**", 34 | "**/reset*.css", 35 | "**/bootstrap*.css", 36 | "**/*.js", 37 | "**/*.jsx" 38 | ] 39 | } 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Nahom_zd 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | To do list 12 | 13 | 14 |
15 |
16 |
17 |
18 |

Today's To Do

19 | 20 |
21 | 22 |
23 | 24 | 25 |
26 | 27 |
    28 |
    29 | 30 |
    31 |
    32 |
    33 |
    34 | 35 | 36 | -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | To do list 12 | 13 | 14 |
    15 |
    16 |
    17 |
    18 |

    Today's To Do

    19 | 20 |
    21 | 22 |
    23 | 24 | 25 |
    26 | 27 |
      28 |
      29 | 30 |
      31 |
      32 |
      33 |
      34 | 35 | 36 | -------------------------------------------------------------------------------- /src/modules/TodosContainer.js: -------------------------------------------------------------------------------- 1 | import Todo from './Todo.js'; 2 | import { getTodos, setTodos } from './store.js'; 3 | import UI from './UI.js'; 4 | 5 | export default class TodosContainer { 6 | addTodo = (description) => { 7 | this.todos = getTodos() || []; 8 | if (description.trim().length !== 0) { 9 | const id = Math.floor(Math.random() * 100000).toString(); 10 | const index = this.todos.length + 1; 11 | const todo = new Todo(id, description, false, index); 12 | this.todos.push(todo); 13 | setTodos(this.todos); 14 | UI.add(id, description, false); 15 | } 16 | }; 17 | 18 | removeTodo = (id) => { 19 | this.todos = getTodos() || []; 20 | this.todos = this.todos 21 | .filter((todo) => todo.id !== id) 22 | .map((todo, index) => ({ ...todo, index: index + 1 })); 23 | setTodos(this.todos); 24 | UI.remove(id); 25 | }; 26 | 27 | updateDescription = (id, description) => { 28 | this.todos = getTodos() || []; 29 | const [updateId] = id.match(/\d+/); 30 | 31 | if (description.trim().length !== 0) { 32 | this.todos = this.todos.map((todo) => { 33 | if (todo.id === updateId) { 34 | return { ...todo, description }; 35 | } 36 | return todo; 37 | }); 38 | setTodos(this.todos); 39 | UI.updateTodo(id, description); 40 | } else { 41 | this.removeTodo(updateId); 42 | } 43 | }; 44 | } 45 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "to-do-list", 3 | "version": "1.0.0", 4 | "description": "To do list app using javascript ,html and css.", 5 | "main": "index.js", 6 | "scripts": { 7 | "deploy": "gh-pages -d dist", 8 | "build": "webpack --mode development", 9 | "start": "webpack serve --mode development --open", 10 | "test": "jest --coverage --env=jsdom", 11 | "watch": "jest --watchAll *.js" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/zdnahom/to-do-list.git" 16 | }, 17 | "keywords": [], 18 | "author": "", 19 | "license": "ISC", 20 | "bugs": { 21 | "url": "https://github.com/zdnahom/to-do-list/issues" 22 | }, 23 | "homepage": "https://github.com/zdnahom/to-do-list", 24 | "devDependencies": { 25 | "@babel/plugin-transform-modules-commonjs": "^7.21.2", 26 | "babel-eslint": "^10.1.0", 27 | "css-loader": "^6.7.3", 28 | "eslint": "^7.32.0", 29 | "eslint-config-airbnb-base": "^14.2.1", 30 | "eslint-plugin-import": "^2.27.5", 31 | "html-webpack-plugin": "^5.5.0", 32 | "jest": "^29.4.3", 33 | "jest-environment-jsdom": "^29.4.3", 34 | "style-loader": "^3.3.1", 35 | "stylelint": "^13.13.1", 36 | "stylelint-config-standard": "^21.0.0", 37 | "stylelint-csstree-validator": "^1.9.0", 38 | "stylelint-scss": "^3.21.0", 39 | "webpack": "^5.75.0", 40 | "webpack-cli": "^5.0.1", 41 | "webpack-dev-server": "^4.11.1" 42 | }, 43 | "dependencies": { 44 | "gh-pages": "^5.0.0" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import './style.css'; 2 | import { getTodos } from './modules/store.js'; 3 | import populateTodos from './modules/generateTodo.js'; 4 | import TodosContainer from './modules/TodosContainer.js'; 5 | import { updateStatus, clearTodoList } from './modules/updateStatus.js'; 6 | 7 | const todoLists = getTodos() || []; 8 | const container = new TodosContainer(); 9 | 10 | const todoElements = document.querySelector('.tasks'); 11 | const form = document.querySelector('.task-adder'); 12 | const { task } = form.elements; 13 | const clearButton = document.querySelector('.button-wrapper button'); 14 | 15 | form.addEventListener('submit', (event) => { 16 | event.preventDefault(); 17 | container.addTodo(task.value); 18 | task.value = ''; 19 | }); 20 | 21 | todoElements.addEventListener('click', (event) => { 22 | const { target } = event; 23 | if (parseInt(target.id, 10)) { 24 | container.removeTodo(event.target.id); 25 | } else if (target.id.includes('description')) { 26 | target.parentNode.parentNode.style.backgroundColor = 'rgb(253, 238, 213)'; 27 | target.addEventListener('blur', () => { 28 | target.parentNode.parentNode.style.backgroundColor = 'white'; 29 | container.updateDescription(target.id, target.value); 30 | }); 31 | target.addEventListener('keypress', (event) => { 32 | if (event.key === 'Enter') { 33 | target.blur(); 34 | } 35 | }); 36 | } 37 | }); 38 | 39 | todoElements.addEventListener('change', (event) => { 40 | if (event.target.id.includes('checkbox')) { 41 | updateStatus(event.target.id); 42 | } 43 | }); 44 | 45 | clearButton.addEventListener('click', () => { 46 | clearTodoList(); 47 | }); 48 | 49 | window.addEventListener('DOMContentLoaded', () => { 50 | populateTodos(todoLists); 51 | }); 52 | -------------------------------------------------------------------------------- /src/modules/UI.js: -------------------------------------------------------------------------------- 1 | export default class UI { 2 | static remove = (id) => { 3 | const element = document.getElementById(id); 4 | const parentToRemove = element.parentNode.parentNode; 5 | parentToRemove.remove(); 6 | }; 7 | 8 | static add = (id, description, status) => { 9 | const li = document.createElement('li'); 10 | li.className = 'todo'; 11 | li.innerHTML = ` 12 |
      13 | 14 | 15 |
      16 | 19 | `; 20 | 21 | document.querySelector('.tasks').appendChild(li); 22 | document.querySelector(`#checkbox-${id}`).checked = status; 23 | if (document.querySelector(`#checkbox-${id}`).checked) { 24 | document.querySelector(`#description-${id}`).style.color = 'gray'; 25 | document.querySelector(`#description-${id}`).style.textDecoration = 'line-through'; 26 | } else { 27 | document.querySelector(`#description-${id}`).style.color = 'black'; 28 | document.querySelector(`#description-${id}`).style.textDecoration = 'none'; 29 | } 30 | }; 31 | 32 | static updateTodo=(id, description) => { 33 | const updateTaskElement = document.querySelector(`#${id}`); 34 | updateTaskElement.value = description; 35 | } 36 | 37 | static updateStatusUI=(id) => { 38 | const checkbox = document.querySelector(`#checkbox-${id}`); 39 | const descriptionElement = document.querySelector(`#description-${id}`); 40 | if (checkbox.checked) { 41 | descriptionElement.style.color = 'gray'; 42 | descriptionElement.style.textDecoration = 'line-through'; 43 | } else { 44 | descriptionElement.style.color = 'black'; 45 | descriptionElement.style.textDecoration = 'none'; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | 84 | # Gatsby files 85 | .cache/ 86 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 87 | # https://nextjs.org/blog/next-9-1#public-directory-support 88 | # public 89 | 90 | # vuepress build output 91 | .vuepress/dist 92 | 93 | # Serverless directories 94 | .serverless/ 95 | 96 | # FuseBox cache 97 | .fusebox/ 98 | 99 | # DynamoDB Local files 100 | .dynamodb/ 101 | 102 | # TernJS port file 103 | .tern-port 104 | -------------------------------------------------------------------------------- /.github/workflows/linter.yml: -------------------------------------------------------------------------------- 1 | name: Linters 2 | 3 | on: pull_request 4 | 5 | env: 6 | FORCE_COLOR: 1 7 | 8 | jobs: 9 | lighthouse: 10 | name: Lighthouse 11 | runs-on: ubuntu-22.04 12 | steps: 13 | - uses: actions/checkout@v2 14 | - uses: actions/setup-node@v1 15 | with: 16 | node-version: "12.x" 17 | - name: Setup Lighthouse 18 | run: npm install -g @lhci/cli@0.7.x 19 | - name: Lighthouse Report 20 | run: lhci autorun --upload.target=temporary-public-storage --collect.staticDistDir=. 21 | webhint: 22 | name: Webhint 23 | runs-on: ubuntu-22.04 24 | steps: 25 | - uses: actions/checkout@v2 26 | - uses: actions/setup-node@v1 27 | with: 28 | node-version: "12.x" 29 | - name: Setup Webhint 30 | run: | 31 | npm install --save-dev hint@7.x 32 | [ -f .hintrc ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/html-css-js/.hintrc 33 | - name: Webhint Report 34 | run: npx hint . 35 | stylelint: 36 | name: Stylelint 37 | runs-on: ubuntu-22.04 38 | steps: 39 | - uses: actions/checkout@v2 40 | - uses: actions/setup-node@v1 41 | with: 42 | node-version: "12.x" 43 | - name: Setup Stylelint 44 | run: | 45 | npm install --save-dev stylelint@13.x stylelint-scss@3.x stylelint-config-standard@21.x stylelint-csstree-validator@1.x 46 | [ -f .stylelintrc.json ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/html-css-js/.stylelintrc.json 47 | - name: Stylelint Report 48 | run: npx stylelint "**/*.{css,scss}" 49 | eslint: 50 | name: ESLint 51 | runs-on: ubuntu-22.04 52 | steps: 53 | - uses: actions/checkout@v2 54 | - uses: actions/setup-node@v1 55 | with: 56 | node-version: "12.x" 57 | - name: Setup ESLint 58 | run: | 59 | npm install --save-dev eslint@7.x eslint-config-airbnb-base@14.x eslint-plugin-import@2.x babel-eslint@10.x 60 | [ -f .eslintrc.json ] || wget https://raw.githubusercontent.com/microverseinc/linters-config/master/html-css-js/.eslintrc.json 61 | - name: ESLint Report 62 | run: npx eslint . 63 | nodechecker: 64 | name: node_modules checker 65 | runs-on: ubuntu-22.04 66 | steps: 67 | - uses: actions/checkout@v2 68 | - name: Check node_modules existence 69 | run: | 70 | if [ -d "node_modules/" ]; then echo -e "\e[1;31mThe node_modules/ folder was pushed to the repo. Please remove it from the GitHub repository and try again."; echo -e "\e[1;32mYou can set up a .gitignore file with this folder included on it to prevent this from happening in the future." && exit 1; fi 71 | -------------------------------------------------------------------------------- /src/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | body { 8 | background-color: #d2d2d2; 9 | } 10 | 11 | .tasks-wrapper { 12 | width: 40%; 13 | background-color: white; 14 | margin: 100px auto; 15 | } 16 | 17 | .tasks-wrapper i { 18 | color: gray; 19 | } 20 | 21 | .tasks-header { 22 | display: flex; 23 | justify-content: space-between; 24 | align-items: center; 25 | padding: 3%; 26 | border-bottom: 1px solid #d2d2d2; 27 | } 28 | 29 | .tasks-header h3 { 30 | font-size: 1em; 31 | font-weight: 400; 32 | color: #6b6262; 33 | } 34 | 35 | .tasks-header i { 36 | font-size: 0.8em; 37 | } 38 | 39 | .task-adder { 40 | display: flex; 41 | justify-content: space-between; 42 | align-items: center; 43 | border-bottom: 1px solid #d2d2d2; 44 | padding: 3%; 45 | } 46 | 47 | .task-adder input { 48 | width: 100%; 49 | border: none; 50 | outline: none; 51 | font-size: 1em; 52 | color: #6b6262; 53 | } 54 | 55 | .task-adder button { 56 | background-color: inherit; 57 | border: none; 58 | font-size: 0.8em; 59 | } 60 | 61 | .tasks li { 62 | display: flex; 63 | justify-content: space-between; 64 | align-items: center; 65 | padding: 3%; 66 | border-bottom: 1px solid #d2d2d2; 67 | } 68 | 69 | .tasks div { 70 | display: flex; 71 | align-items: center; 72 | gap: 0.8em; 73 | width: 100%; 74 | } 75 | 76 | .tasks input[type='checkbox'] { 77 | width: 22px !important; 78 | height: 22px !important; 79 | display: flex; 80 | align-items: center; 81 | justify-content: center; 82 | margin: 5px; 83 | -webkit-appearance: none; 84 | -moz-appearance: none; 85 | -o-appearance: none; 86 | appearance: none; 87 | outline: 1px solid rgb(226, 219, 219); 88 | box-shadow: none; 89 | text-align: center; 90 | line-height: 1em; 91 | background: white; 92 | } 93 | 94 | .tasks input[type='checkbox']:checked::after { 95 | content: '✔'; 96 | color: green; 97 | font-size: 1.4em; 98 | font-weight: 900; 99 | } 100 | 101 | .tasks input[type='text'] { 102 | width: 100%; 103 | font-size: 1em; 104 | border: none; 105 | background-color: inherit; 106 | outline: none; 107 | } 108 | 109 | .tasks button { 110 | background-color: inherit; 111 | border: none; 112 | cursor: pointer; 113 | } 114 | 115 | .tasks button i:hover { 116 | color: red; 117 | } 118 | 119 | .button-wrapper { 120 | display: flex; 121 | justify-content: center; 122 | background-color: #f7f2f2; 123 | } 124 | 125 | .button-wrapper button { 126 | background-color: inherit; 127 | border: none; 128 | padding: 3%; 129 | cursor: pointer; 130 | font-size: 1em; 131 | color: #6b6262; 132 | } 133 | 134 | .button-wrapper button:hover { 135 | color: black; 136 | text-decoration: underline; 137 | } 138 | -------------------------------------------------------------------------------- /src/todolist.test.js: -------------------------------------------------------------------------------- 1 | import TodosContainer from './modules/TodosContainer.js'; 2 | import { getTodos } from './modules/store.js'; 3 | import { updateStatus, clearTodoList } from './modules/updateStatus.js'; 4 | 5 | // Set up our document body 6 | document.body.innerHTML = ` 7 | 9 | `; 10 | 11 | describe('Test Add todo', () => { 12 | it('Add a valid todo', () => { 13 | // arrange 14 | const container = new TodosContainer(); 15 | 16 | // act 17 | container.addTodo('read books'); 18 | container.addTodo('dance'); 19 | container.addTodo('code for 1 hour'); 20 | container.addTodo('Eat salad'); 21 | const tasks = document.querySelectorAll('.tasks li'); 22 | 23 | // assert 24 | expect(tasks).toHaveLength(4); 25 | }); 26 | 27 | it('Add empty todo', () => { 28 | // arrange 29 | const container = new TodosContainer(); 30 | 31 | // act 32 | container.addTodo(' '); 33 | const tasks = document.querySelectorAll('.tasks li'); 34 | 35 | // assert 36 | expect(tasks).toHaveLength(4); 37 | }); 38 | }); 39 | 40 | describe('Test Remove todo', () => { 41 | it('Remove a todo with id=1', () => { 42 | // arrange 43 | const container = new TodosContainer(); 44 | let tasks = document.querySelectorAll('.tasks li'); 45 | const task = tasks[0].querySelector('i'); 46 | 47 | // act 48 | container.removeTodo(task.id); 49 | tasks = document.querySelectorAll('.tasks li'); 50 | 51 | // assert 52 | expect(tasks).toHaveLength(3); 53 | }); 54 | }); 55 | 56 | describe('Test Update todo', () => { 57 | it('Update todo item description', () => { 58 | // arrange 59 | const container = new TodosContainer(); 60 | const tasks = document.querySelectorAll('.tasks li'); 61 | const task = tasks[0].querySelector('input[type="text"]'); 62 | 63 | // act 64 | container.updateDescription(task.id, 'Read more books'); 65 | 66 | // assert 67 | expect(task.value).toEqual('Read more books'); 68 | }); 69 | 70 | it('Update todo item description with empty string', () => { 71 | // arrange 72 | const container = new TodosContainer(); 73 | let tasks = document.querySelectorAll('.tasks li'); 74 | const task = tasks[0].querySelector('input[type="text"]'); 75 | 76 | // act 77 | container.updateDescription(task.id, ''); 78 | tasks = document.querySelectorAll('.tasks li'); 79 | 80 | // assert 81 | expect(tasks).toHaveLength(2); 82 | }); 83 | }); 84 | 85 | describe('Test for completed status', () => { 86 | it('change todo list status to true', () => { 87 | // arrange 88 | const tasks = document.querySelectorAll('.tasks li'); 89 | const task1 = tasks[0].querySelector('input[type="checkbox"]'); 90 | const task2 = tasks[1].querySelector('input[type="checkbox"]'); 91 | 92 | // act 93 | updateStatus(task1.id); 94 | updateStatus(task2.id); 95 | 96 | // assert 97 | expect(getTodos()[0].completed).toBe(true); 98 | }); 99 | it('change todo list status to false', () => { 100 | // arrange 101 | const tasks = document.querySelectorAll('.tasks li'); 102 | const task = tasks[0].querySelector('input[type="checkbox"]'); 103 | 104 | // act 105 | updateStatus(task.id); 106 | 107 | // assert 108 | expect(getTodos()[0].completed).toBe(false); 109 | }); 110 | }); 111 | 112 | describe('Test for Clear completed', () => { 113 | it('clear completed tasks', () => { 114 | // arrange 115 | let tasks = document.querySelectorAll('.tasks li'); 116 | 117 | // act 118 | clearTodoList(); 119 | tasks = document.querySelectorAll('.tasks li'); 120 | 121 | // assert 122 | expect(tasks).toHaveLength(1); 123 | }); 124 | }); 125 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 📗 Table of Contents 4 | 5 | - [📗 Table of Contents](#-table-of-contents) 6 | - [📖 To do list](#-to-do-list) 7 | - [🛠 Built With ](#-built-with-) 8 | - [Tech Stack ](#tech-stack-) 9 | - [Key Features ](#key-features-) 10 | - [🚀 Live Demo ](#-live-demo-) 11 | - [💻 Getting Started ](#-getting-started-) 12 | - [Prerequisites](#prerequisites) 13 | - [Setup](#setup) 14 | - [Install](#install) 15 | - [Usage](#usage) 16 | - [Run tests](#run-tests) 17 | - [👥 Authors ](#-authors-) 18 | - [🔭 Future Features ](#-future-features-) 19 | - [🤝 Contributing ](#-contributing-) 20 | - [⭐️ Show your support ](#️-show-your-support-) 21 | - [🙏 Acknowledgments ](#-acknowledgments-) 22 | - [❓ FAQ (OPTIONAL) ](#-faq-optional-) 23 | - [📝 License ](#-license-) 24 | 25 | 26 | 27 | # 📖 To do list 28 | > 29 | To do list is a task management project built using pure javascript(ES6) , HTML, CSS, and Webpack. 30 | 31 | ## 🛠 Built With 32 | 33 | ### Tech Stack 34 | 35 |
      36 | Client 37 | 42 |
      43 |
      44 | Server 45 | 49 |
      50 | 51 | 52 | 53 | 54 | ### Key Features 55 | 56 | - **Display todo lists** 57 | - **Add new todo list** 58 | - **Remove todo list** 59 | - **Update todo list** 60 | - **Clear all completed todo lists** 61 | 62 | 63 | 64 | 65 |

      (back to top)

      66 | 67 | 68 | 69 | ## 🚀 Live Demo 70 | 71 | - [Live Demo](https://zdnahom.github.io/to-do-list/) 72 | 73 |

      (back to top)

      74 | 75 | 76 | ## 💻 Getting Started 77 | 78 | 79 | ### Prerequisites 80 | 81 | In order to run this project you need: Configure your code editor with HTML , CSS & JS and some other important extensions 82 | 83 | 84 | 85 | ### Setup 86 | 87 | git clone git@github.com:zdnahom/to-do-list.git 88 | 89 | 90 | 91 | ### Install 92 | 93 | Install this project with: 94 | 95 | git clone git@github.com:zdnahom/to-do-list.git 96 | 97 | 98 | ### Usage 99 | 100 | To run the project, execute the following command: 101 | - cd to-do-list 102 | - npm install 103 | - npm start 104 | 105 | ### Run tests 106 | 107 | To run tests, run the following command: No test module for now.But it will be added in the near future 108 | 109 | 110 | 111 | 112 | ## 👥 Authors 113 | 114 | 👤 **Nahom Zerihun Demissie 💻** 115 | - GitHub: [@zdnahom](https://github.com/zdnahom/) 116 | 117 | 118 |

      (back to top)

      119 | 120 | 121 | 122 | ## 🔭 Future Features 123 | 124 | - **Add drag and drop functionality** 125 | - **Add cool animations** 126 | 127 | 128 | 129 | 130 |

      (back to top)

      131 | 132 | 133 | 134 | ## 🤝 Contributing 135 | 136 | Contributions, issues, and feature requests are welcome! 137 | 138 | Feel free to check the [issues page](../../issues/). 139 | 140 |

      (back to top)

      141 | 142 | 143 | 144 | ## ⭐️ Show your support 145 | 146 | If you like this project , please clone it and try it . I know you're going to love it 147 | 148 |

      (back to top)

      149 | 150 | 151 | 152 | ## 🙏 Acknowledgments 153 | I would like to thank Microverse(staffs , mentors , reviewers) giving me the knowledge to build an amazing project like this. 154 | 155 |

      (back to top)

      156 | 157 | 158 | 159 | ## ❓ FAQ (OPTIONAL) 160 | 161 | - **Can I fork the project and make a contribution?** 162 | 163 | Of course you can! First fork it and contribute to it. 164 | 165 | - **How should I ask a pull request** 166 | 167 | - Step 1 : Click on the pull request button 168 | - Step 2 : create pull request 169 | 170 |

      (back to top)

      171 | 172 | 173 | 174 | ## 📝 License 175 | 176 | This project is [MIT](./LICENSE) licensed. 177 | 178 | _NOTE: we recommend using the [MIT license](https://choosealicense.com/licenses/mit/) - you can set it up quickly by [using templates available on GitHub](https://docs.github.com/en/communities/setting-up-your-project-for-healthy-contributions/adding-a-license-to-a-repository). You can also use [any other license](https://choosealicense.com/licenses/) if you wish._ 179 | 180 |

      (back to top)

      181 | -------------------------------------------------------------------------------- /dist/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development"). 3 | * This devtool is neither made for production nor for readable output files. 4 | * It uses "eval()" calls to create a separate source file in the browser devtools. 5 | * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) 6 | * or disable the default devtool with "devtool: false". 7 | * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). 8 | */ 9 | /******/ (() => { // webpackBootstrap 10 | /******/ "use strict"; 11 | /******/ var __webpack_modules__ = ({ 12 | 13 | /***/ "./node_modules/css-loader/dist/cjs.js!./src/style.css": 14 | /*!*************************************************************!*\ 15 | !*** ./node_modules/css-loader/dist/cjs.js!./src/style.css ***! 16 | \*************************************************************/ 17 | /***/ ((module, __webpack_exports__, __webpack_require__) => { 18 | 19 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/noSourceMaps.js */ \"./node_modules/css-loader/dist/runtime/noSourceMaps.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);\n// Imports\n\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \"* {\\r\\n box-sizing: border-box;\\r\\n margin: 0;\\r\\n padding: 0;\\r\\n}\\r\\n\\r\\nbody {\\r\\n background-color: #d2d2d2;\\r\\n}\\r\\n\\r\\n.tasks-wrapper {\\r\\n width: 40%;\\r\\n background-color: white;\\r\\n margin: 100px auto;\\r\\n}\\r\\n\\r\\n.tasks-wrapper i {\\r\\n color: gray;\\r\\n}\\r\\n\\r\\n.tasks-header {\\r\\n display: flex;\\r\\n justify-content: space-between;\\r\\n align-items: center;\\r\\n padding: 3%;\\r\\n border-bottom: 1px solid #d2d2d2;\\r\\n}\\r\\n\\r\\n.tasks-header h3 {\\r\\n font-size: 1em;\\r\\n font-weight: 400;\\r\\n color: #6b6262;\\r\\n}\\r\\n\\r\\n.tasks-header i {\\r\\n font-size: 0.8em;\\r\\n}\\r\\n\\r\\n.task-adder {\\r\\n display: flex;\\r\\n justify-content: space-between;\\r\\n align-items: center;\\r\\n border-bottom: 1px solid #d2d2d2;\\r\\n padding: 3%;\\r\\n}\\r\\n\\r\\n.task-adder input {\\r\\n width: 100%;\\r\\n border: none;\\r\\n outline: none;\\r\\n font-size: 1em;\\r\\n color: #6b6262;\\r\\n}\\r\\n\\r\\n.task-adder button {\\r\\n background-color: inherit;\\r\\n border: none;\\r\\n font-size: 0.8em;\\r\\n}\\r\\n\\r\\n.tasks li {\\r\\n display: flex;\\r\\n justify-content: space-between;\\r\\n align-items: center;\\r\\n padding: 3%;\\r\\n border-bottom: 1px solid #d2d2d2;\\r\\n}\\r\\n\\r\\n.tasks div {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n gap: 0.8em;\\r\\n width: 100%;\\r\\n}\\r\\n\\r\\n.tasks input[type='checkbox'] {\\r\\n width: 22px !important;\\r\\n height: 22px !important;\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: center;\\r\\n margin: 5px;\\r\\n -webkit-appearance: none;\\r\\n -moz-appearance: none;\\r\\n -o-appearance: none;\\r\\n appearance: none;\\r\\n outline: 1px solid rgb(226, 219, 219);\\r\\n box-shadow: none;\\r\\n text-align: center;\\r\\n line-height: 1em;\\r\\n background: white;\\r\\n}\\r\\n\\r\\n.tasks input[type='checkbox']:checked::after {\\r\\n content: '✔';\\r\\n color: green;\\r\\n font-size: 1.4em;\\r\\n font-weight: 900;\\r\\n}\\r\\n\\r\\n.tasks input[type='text'] {\\r\\n width: 100%;\\r\\n font-size: 1em;\\r\\n border: none;\\r\\n background-color: inherit;\\r\\n outline: none;\\r\\n}\\r\\n\\r\\n.tasks button {\\r\\n background-color: inherit;\\r\\n border: none;\\r\\n cursor: pointer;\\r\\n}\\r\\n\\r\\n.tasks button i:hover {\\r\\n color: red;\\r\\n}\\r\\n\\r\\n.button-wrapper {\\r\\n display: flex;\\r\\n justify-content: center;\\r\\n background-color: #f7f2f2;\\r\\n}\\r\\n\\r\\n.button-wrapper button {\\r\\n background-color: inherit;\\r\\n border: none;\\r\\n padding: 3%;\\r\\n cursor: pointer;\\r\\n font-size: 1em;\\r\\n color: #6b6262;\\r\\n}\\r\\n\\r\\n.button-wrapper button:hover {\\r\\n color: black;\\r\\n text-decoration: underline;\\r\\n}\\r\\n\", \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://to-do-list/./src/style.css?./node_modules/css-loader/dist/cjs.js"); 20 | 21 | /***/ }), 22 | 23 | /***/ "./node_modules/css-loader/dist/runtime/api.js": 24 | /*!*****************************************************!*\ 25 | !*** ./node_modules/css-loader/dist/runtime/api.js ***! 26 | \*****************************************************/ 27 | /***/ ((module) => { 28 | 29 | eval("\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\nmodule.exports = function (cssWithMappingToString) {\n var list = [];\n\n // return the list of modules as css string\n list.toString = function toString() {\n return this.map(function (item) {\n var content = \"\";\n var needLayer = typeof item[5] !== \"undefined\";\n if (item[4]) {\n content += \"@supports (\".concat(item[4], \") {\");\n }\n if (item[2]) {\n content += \"@media \".concat(item[2], \" {\");\n }\n if (needLayer) {\n content += \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\");\n }\n content += cssWithMappingToString(item);\n if (needLayer) {\n content += \"}\";\n }\n if (item[2]) {\n content += \"}\";\n }\n if (item[4]) {\n content += \"}\";\n }\n return content;\n }).join(\"\");\n };\n\n // import a list of modules into the list\n list.i = function i(modules, media, dedupe, supports, layer) {\n if (typeof modules === \"string\") {\n modules = [[null, modules, undefined]];\n }\n var alreadyImportedModules = {};\n if (dedupe) {\n for (var k = 0; k < this.length; k++) {\n var id = this[k][0];\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n for (var _k = 0; _k < modules.length; _k++) {\n var item = [].concat(modules[_k]);\n if (dedupe && alreadyImportedModules[item[0]]) {\n continue;\n }\n if (typeof layer !== \"undefined\") {\n if (typeof item[5] === \"undefined\") {\n item[5] = layer;\n } else {\n item[1] = \"@layer\".concat(item[5].length > 0 ? \" \".concat(item[5]) : \"\", \" {\").concat(item[1], \"}\");\n item[5] = layer;\n }\n }\n if (media) {\n if (!item[2]) {\n item[2] = media;\n } else {\n item[1] = \"@media \".concat(item[2], \" {\").concat(item[1], \"}\");\n item[2] = media;\n }\n }\n if (supports) {\n if (!item[4]) {\n item[4] = \"\".concat(supports);\n } else {\n item[1] = \"@supports (\".concat(item[4], \") {\").concat(item[1], \"}\");\n item[4] = supports;\n }\n }\n list.push(item);\n }\n };\n return list;\n};\n\n//# sourceURL=webpack://to-do-list/./node_modules/css-loader/dist/runtime/api.js?"); 30 | 31 | /***/ }), 32 | 33 | /***/ "./node_modules/css-loader/dist/runtime/noSourceMaps.js": 34 | /*!**************************************************************!*\ 35 | !*** ./node_modules/css-loader/dist/runtime/noSourceMaps.js ***! 36 | \**************************************************************/ 37 | /***/ ((module) => { 38 | 39 | eval("\n\nmodule.exports = function (i) {\n return i[1];\n};\n\n//# sourceURL=webpack://to-do-list/./node_modules/css-loader/dist/runtime/noSourceMaps.js?"); 40 | 41 | /***/ }), 42 | 43 | /***/ "./src/style.css": 44 | /*!***********************!*\ 45 | !*** ./src/style.css ***! 46 | \***********************/ 47 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 48 | 49 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js */ \"./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/styleDomAPI.js */ \"./node_modules/style-loader/dist/runtime/styleDomAPI.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1__);\n/* harmony import */ var _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/insertBySelector.js */ \"./node_modules/style-loader/dist/runtime/insertBySelector.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js */ \"./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/insertStyleElement.js */ \"./node_modules/style-loader/dist/runtime/insertStyleElement.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/styleTagTransform.js */ \"./node_modules/style-loader/dist/runtime/styleTagTransform.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var _node_modules_css_loader_dist_cjs_js_style_css__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! !!../node_modules/css-loader/dist/cjs.js!./style.css */ \"./node_modules/css-loader/dist/cjs.js!./src/style.css\");\n\n \n \n \n \n \n \n \n \n \n\nvar options = {};\n\noptions.styleTagTransform = (_node_modules_style_loader_dist_runtime_styleTagTransform_js__WEBPACK_IMPORTED_MODULE_5___default());\noptions.setAttributes = (_node_modules_style_loader_dist_runtime_setAttributesWithoutAttributes_js__WEBPACK_IMPORTED_MODULE_3___default());\n\n options.insert = _node_modules_style_loader_dist_runtime_insertBySelector_js__WEBPACK_IMPORTED_MODULE_2___default().bind(null, \"head\");\n \noptions.domAPI = (_node_modules_style_loader_dist_runtime_styleDomAPI_js__WEBPACK_IMPORTED_MODULE_1___default());\noptions.insertStyleElement = (_node_modules_style_loader_dist_runtime_insertStyleElement_js__WEBPACK_IMPORTED_MODULE_4___default());\n\nvar update = _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default()(_node_modules_css_loader_dist_cjs_js_style_css__WEBPACK_IMPORTED_MODULE_6__[\"default\"], options);\n\n\n\n\n /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (_node_modules_css_loader_dist_cjs_js_style_css__WEBPACK_IMPORTED_MODULE_6__[\"default\"] && _node_modules_css_loader_dist_cjs_js_style_css__WEBPACK_IMPORTED_MODULE_6__[\"default\"].locals ? _node_modules_css_loader_dist_cjs_js_style_css__WEBPACK_IMPORTED_MODULE_6__[\"default\"].locals : undefined);\n\n\n//# sourceURL=webpack://to-do-list/./src/style.css?"); 50 | 51 | /***/ }), 52 | 53 | /***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js": 54 | /*!****************************************************************************!*\ 55 | !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***! 56 | \****************************************************************************/ 57 | /***/ ((module) => { 58 | 59 | eval("\n\nvar stylesInDOM = [];\n\nfunction getIndexByIdentifier(identifier) {\n var result = -1;\n\n for (var i = 0; i < stylesInDOM.length; i++) {\n if (stylesInDOM[i].identifier === identifier) {\n result = i;\n break;\n }\n }\n\n return result;\n}\n\nfunction modulesToDom(list, options) {\n var idCountMap = {};\n var identifiers = [];\n\n for (var i = 0; i < list.length; i++) {\n var item = list[i];\n var id = options.base ? item[0] + options.base : item[0];\n var count = idCountMap[id] || 0;\n var identifier = \"\".concat(id, \" \").concat(count);\n idCountMap[id] = count + 1;\n var indexByIdentifier = getIndexByIdentifier(identifier);\n var obj = {\n css: item[1],\n media: item[2],\n sourceMap: item[3],\n supports: item[4],\n layer: item[5]\n };\n\n if (indexByIdentifier !== -1) {\n stylesInDOM[indexByIdentifier].references++;\n stylesInDOM[indexByIdentifier].updater(obj);\n } else {\n var updater = addElementStyle(obj, options);\n options.byIndex = i;\n stylesInDOM.splice(i, 0, {\n identifier: identifier,\n updater: updater,\n references: 1\n });\n }\n\n identifiers.push(identifier);\n }\n\n return identifiers;\n}\n\nfunction addElementStyle(obj, options) {\n var api = options.domAPI(options);\n api.update(obj);\n\n var updater = function updater(newObj) {\n if (newObj) {\n if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap && newObj.supports === obj.supports && newObj.layer === obj.layer) {\n return;\n }\n\n api.update(obj = newObj);\n } else {\n api.remove();\n }\n };\n\n return updater;\n}\n\nmodule.exports = function (list, options) {\n options = options || {};\n list = list || [];\n var lastIdentifiers = modulesToDom(list, options);\n return function update(newList) {\n newList = newList || [];\n\n for (var i = 0; i < lastIdentifiers.length; i++) {\n var identifier = lastIdentifiers[i];\n var index = getIndexByIdentifier(identifier);\n stylesInDOM[index].references--;\n }\n\n var newLastIdentifiers = modulesToDom(newList, options);\n\n for (var _i = 0; _i < lastIdentifiers.length; _i++) {\n var _identifier = lastIdentifiers[_i];\n\n var _index = getIndexByIdentifier(_identifier);\n\n if (stylesInDOM[_index].references === 0) {\n stylesInDOM[_index].updater();\n\n stylesInDOM.splice(_index, 1);\n }\n }\n\n lastIdentifiers = newLastIdentifiers;\n };\n};\n\n//# sourceURL=webpack://to-do-list/./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js?"); 60 | 61 | /***/ }), 62 | 63 | /***/ "./node_modules/style-loader/dist/runtime/insertBySelector.js": 64 | /*!********************************************************************!*\ 65 | !*** ./node_modules/style-loader/dist/runtime/insertBySelector.js ***! 66 | \********************************************************************/ 67 | /***/ ((module) => { 68 | 69 | eval("\n\nvar memo = {};\n/* istanbul ignore next */\n\nfunction getTarget(target) {\n if (typeof memo[target] === \"undefined\") {\n var styleTarget = document.querySelector(target); // Special case to return head of iframe instead of iframe itself\n\n if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n try {\n // This will throw an exception if access to iframe is blocked\n // due to cross-origin restrictions\n styleTarget = styleTarget.contentDocument.head;\n } catch (e) {\n // istanbul ignore next\n styleTarget = null;\n }\n }\n\n memo[target] = styleTarget;\n }\n\n return memo[target];\n}\n/* istanbul ignore next */\n\n\nfunction insertBySelector(insert, style) {\n var target = getTarget(insert);\n\n if (!target) {\n throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.\");\n }\n\n target.appendChild(style);\n}\n\nmodule.exports = insertBySelector;\n\n//# sourceURL=webpack://to-do-list/./node_modules/style-loader/dist/runtime/insertBySelector.js?"); 70 | 71 | /***/ }), 72 | 73 | /***/ "./node_modules/style-loader/dist/runtime/insertStyleElement.js": 74 | /*!**********************************************************************!*\ 75 | !*** ./node_modules/style-loader/dist/runtime/insertStyleElement.js ***! 76 | \**********************************************************************/ 77 | /***/ ((module) => { 78 | 79 | eval("\n\n/* istanbul ignore next */\nfunction insertStyleElement(options) {\n var element = document.createElement(\"style\");\n options.setAttributes(element, options.attributes);\n options.insert(element, options.options);\n return element;\n}\n\nmodule.exports = insertStyleElement;\n\n//# sourceURL=webpack://to-do-list/./node_modules/style-loader/dist/runtime/insertStyleElement.js?"); 80 | 81 | /***/ }), 82 | 83 | /***/ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js": 84 | /*!**********************************************************************************!*\ 85 | !*** ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js ***! 86 | \**********************************************************************************/ 87 | /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 88 | 89 | eval("\n\n/* istanbul ignore next */\nfunction setAttributesWithoutAttributes(styleElement) {\n var nonce = true ? __webpack_require__.nc : 0;\n\n if (nonce) {\n styleElement.setAttribute(\"nonce\", nonce);\n }\n}\n\nmodule.exports = setAttributesWithoutAttributes;\n\n//# sourceURL=webpack://to-do-list/./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js?"); 90 | 91 | /***/ }), 92 | 93 | /***/ "./node_modules/style-loader/dist/runtime/styleDomAPI.js": 94 | /*!***************************************************************!*\ 95 | !*** ./node_modules/style-loader/dist/runtime/styleDomAPI.js ***! 96 | \***************************************************************/ 97 | /***/ ((module) => { 98 | 99 | eval("\n\n/* istanbul ignore next */\nfunction apply(styleElement, options, obj) {\n var css = \"\";\n\n if (obj.supports) {\n css += \"@supports (\".concat(obj.supports, \") {\");\n }\n\n if (obj.media) {\n css += \"@media \".concat(obj.media, \" {\");\n }\n\n var needLayer = typeof obj.layer !== \"undefined\";\n\n if (needLayer) {\n css += \"@layer\".concat(obj.layer.length > 0 ? \" \".concat(obj.layer) : \"\", \" {\");\n }\n\n css += obj.css;\n\n if (needLayer) {\n css += \"}\";\n }\n\n if (obj.media) {\n css += \"}\";\n }\n\n if (obj.supports) {\n css += \"}\";\n }\n\n var sourceMap = obj.sourceMap;\n\n if (sourceMap && typeof btoa !== \"undefined\") {\n css += \"\\n/*# sourceMappingURL=data:application/json;base64,\".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), \" */\");\n } // For old IE\n\n /* istanbul ignore if */\n\n\n options.styleTagTransform(css, styleElement, options.options);\n}\n\nfunction removeStyleElement(styleElement) {\n // istanbul ignore if\n if (styleElement.parentNode === null) {\n return false;\n }\n\n styleElement.parentNode.removeChild(styleElement);\n}\n/* istanbul ignore next */\n\n\nfunction domAPI(options) {\n var styleElement = options.insertStyleElement(options);\n return {\n update: function update(obj) {\n apply(styleElement, options, obj);\n },\n remove: function remove() {\n removeStyleElement(styleElement);\n }\n };\n}\n\nmodule.exports = domAPI;\n\n//# sourceURL=webpack://to-do-list/./node_modules/style-loader/dist/runtime/styleDomAPI.js?"); 100 | 101 | /***/ }), 102 | 103 | /***/ "./node_modules/style-loader/dist/runtime/styleTagTransform.js": 104 | /*!*********************************************************************!*\ 105 | !*** ./node_modules/style-loader/dist/runtime/styleTagTransform.js ***! 106 | \*********************************************************************/ 107 | /***/ ((module) => { 108 | 109 | eval("\n\n/* istanbul ignore next */\nfunction styleTagTransform(css, styleElement) {\n if (styleElement.styleSheet) {\n styleElement.styleSheet.cssText = css;\n } else {\n while (styleElement.firstChild) {\n styleElement.removeChild(styleElement.firstChild);\n }\n\n styleElement.appendChild(document.createTextNode(css));\n }\n}\n\nmodule.exports = styleTagTransform;\n\n//# sourceURL=webpack://to-do-list/./node_modules/style-loader/dist/runtime/styleTagTransform.js?"); 110 | 111 | /***/ }), 112 | 113 | /***/ "./src/index.js": 114 | /*!**********************!*\ 115 | !*** ./src/index.js ***! 116 | \**********************/ 117 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 118 | 119 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _style_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./style.css */ \"./src/style.css\");\n/* harmony import */ var _modules_store_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./modules/store.js */ \"./src/modules/store.js\");\n/* harmony import */ var _modules_TodosContainer_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./modules/TodosContainer.js */ \"./src/modules/TodosContainer.js\");\n/* harmony import */ var _modules_updateStatus_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./modules/updateStatus.js */ \"./src/modules/updateStatus.js\");\n/* harmony import */ var _modules_UI_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./modules/UI.js */ \"./src/modules/UI.js\");\n\r\n\r\n\r\n\r\n\r\n\r\nconst todoLists = (0,_modules_store_js__WEBPACK_IMPORTED_MODULE_1__.getTodos)() || [];\r\nconst container = new _modules_TodosContainer_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"]();\r\n\r\nconst form = document.querySelector('.task-adder');\r\nconst todoElements = document.querySelector('.tasks');\r\nconst { task } = form.elements;\r\nconst clearButton = document.querySelector('.button-wrapper button');\r\nfunction populateTodos(data) {\r\n data.forEach((element) => {\r\n _modules_UI_js__WEBPACK_IMPORTED_MODULE_4__[\"default\"].add(element.id, element.description, element.completed);\r\n });\r\n}\r\nform.addEventListener('submit', (event) => {\r\n event.preventDefault();\r\n container.addTodo(task.value);\r\n task.value = '';\r\n});\r\ntodoElements.addEventListener('click', (event) => {\r\n const { target } = event;\r\n if (parseInt(target.id, 10)) {\r\n container.removeTodo(event.target.id);\r\n } else if (target.id.includes('description')) {\r\n target.parentNode.parentNode.style.backgroundColor = 'rgb(253, 238, 213)';\r\n target.addEventListener('blur', () => {\r\n target.parentNode.parentNode.style.backgroundColor = 'white';\r\n container.updateDescription(target.id, target.value);\r\n });\r\n target.addEventListener('keypress', (event) => {\r\n if (event.key === 'Enter') {\r\n target.blur();\r\n }\r\n });\r\n }\r\n});\r\ntodoElements.addEventListener('change', (event) => {\r\n if (event.target.id.includes('checkbox')) {\r\n (0,_modules_updateStatus_js__WEBPACK_IMPORTED_MODULE_3__.updateStatus)(event.target.id);\r\n const [statusId] = event.target.id.match(/\\d+/);\r\n const descriptionElement = document.querySelector(`#description-${statusId}`);\r\n if (event.target.checked) {\r\n descriptionElement.style.color = 'gray';\r\n descriptionElement.style.textDecoration = 'line-through';\r\n } else {\r\n descriptionElement.style.color = 'black';\r\n descriptionElement.style.textDecoration = 'none';\r\n }\r\n }\r\n});\r\nclearButton.addEventListener('click', () => {\r\n (0,_modules_updateStatus_js__WEBPACK_IMPORTED_MODULE_3__.clearTodoList)();\r\n});\r\nwindow.addEventListener('DOMContentLoaded', () => {\r\n populateTodos(todoLists);\r\n});\r\n\n\n//# sourceURL=webpack://to-do-list/./src/index.js?"); 120 | 121 | /***/ }), 122 | 123 | /***/ "./src/modules/Todo.js": 124 | /*!*****************************!*\ 125 | !*** ./src/modules/Todo.js ***! 126 | \*****************************/ 127 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 128 | 129 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ Todo)\n/* harmony export */ });\nclass Todo {\r\n constructor(id, description, completed, index) {\r\n this.id = id;\r\n this.description = description;\r\n this.completed = completed;\r\n this.index = index;\r\n }\r\n}\n\n//# sourceURL=webpack://to-do-list/./src/modules/Todo.js?"); 130 | 131 | /***/ }), 132 | 133 | /***/ "./src/modules/TodosContainer.js": 134 | /*!***************************************!*\ 135 | !*** ./src/modules/TodosContainer.js ***! 136 | \***************************************/ 137 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 138 | 139 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ TodosContainer)\n/* harmony export */ });\n/* harmony import */ var _Todo_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Todo.js */ \"./src/modules/Todo.js\");\n/* harmony import */ var _store_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./store.js */ \"./src/modules/store.js\");\n/* harmony import */ var _UI_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./UI.js */ \"./src/modules/UI.js\");\n\r\n\r\n\r\n\r\nclass TodosContainer {\r\n addTodo = (description) => {\r\n this.todos = (0,_store_js__WEBPACK_IMPORTED_MODULE_1__.getTodos)() || [];\r\n if (description.trim().length !== 0) {\r\n const id = (Math.floor(Math.random() * 100000)).toString();\r\n const index = this.todos.length + 1;\r\n const todo = new _Todo_js__WEBPACK_IMPORTED_MODULE_0__[\"default\"](id, description, false, index);\r\n this.todos.push(todo);\r\n (0,_store_js__WEBPACK_IMPORTED_MODULE_1__.setTodos)(this.todos);\r\n _UI_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"].add(id, description, false);\r\n }\r\n };\r\n\r\n removeTodo = (id) => {\r\n this.todos = (0,_store_js__WEBPACK_IMPORTED_MODULE_1__.getTodos)() || [];\r\n this.todos = this.todos\r\n .filter((todo) => todo.id !== id)\r\n .map((todo, index) => ({ ...todo, index: index + 1 }));\r\n (0,_store_js__WEBPACK_IMPORTED_MODULE_1__.setTodos)(this.todos);\r\n _UI_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"].remove(id);\r\n };\r\n\r\n updateDescription=(id, description) => {\r\n this.todos = (0,_store_js__WEBPACK_IMPORTED_MODULE_1__.getTodos)() || [];\r\n const [updateId] = id.match(/\\d+/);\r\n const updateDes = description.match(/\\w+/g) ? description.match(/\\w+/g).join(' ') : '';\r\n if (updateDes.length > 0) {\r\n this.todos = this.todos.map((todo) => {\r\n if (todo.id === updateId) {\r\n return { ...todo, description: updateDes };\r\n }\r\n return todo;\r\n });\r\n (0,_store_js__WEBPACK_IMPORTED_MODULE_1__.setTodos)(this.todos);\r\n } else {\r\n this.removeTodo(updateId);\r\n }\r\n }\r\n}\r\n\n\n//# sourceURL=webpack://to-do-list/./src/modules/TodosContainer.js?"); 140 | 141 | /***/ }), 142 | 143 | /***/ "./src/modules/UI.js": 144 | /*!***************************!*\ 145 | !*** ./src/modules/UI.js ***! 146 | \***************************/ 147 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 148 | 149 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (/* binding */ UI)\n/* harmony export */ });\nclass UI {\r\n static remove = (id) => {\r\n const element = document.getElementById(id);\r\n const parentToRemove = element.parentNode.parentNode;\r\n parentToRemove.remove();\r\n };\r\n\r\n static add = (id, description, status) => {\r\n const li = document.createElement('li');\r\n li.innerHTML = `\r\n
      \r\n \r\n \r\n
      \r\n \r\n `;\r\n\r\n document.querySelector('.tasks').appendChild(li);\r\n document.querySelector(`#checkbox-${id}`).checked = status;\r\n if (document.querySelector(`#checkbox-${id}`).checked) {\r\n document.querySelector(`#description-${id}`).style.color = 'gray';\r\n document.querySelector(`#description-${id}`).style.textDecoration = 'line-through';\r\n } else {\r\n document.querySelector(`#description-${id}`).style.color = 'black';\r\n document.querySelector(`#description-${id}`).style.textDecoration = 'none';\r\n }\r\n };\r\n}\r\n\n\n//# sourceURL=webpack://to-do-list/./src/modules/UI.js?"); 150 | 151 | /***/ }), 152 | 153 | /***/ "./src/modules/store.js": 154 | /*!******************************!*\ 155 | !*** ./src/modules/store.js ***! 156 | \******************************/ 157 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 158 | 159 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"getTodos\": () => (/* binding */ getTodos),\n/* harmony export */ \"setTodos\": () => (/* binding */ setTodos)\n/* harmony export */ });\nconst getTodos = () => JSON.parse(localStorage.getItem('todos'));\r\nconst setTodos = (obj) => {\r\n localStorage.setItem('todos', JSON.stringify(obj));\r\n};\n\n//# sourceURL=webpack://to-do-list/./src/modules/store.js?"); 160 | 161 | /***/ }), 162 | 163 | /***/ "./src/modules/updateStatus.js": 164 | /*!*************************************!*\ 165 | !*** ./src/modules/updateStatus.js ***! 166 | \*************************************/ 167 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 168 | 169 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"clearTodoList\": () => (/* binding */ clearTodoList),\n/* harmony export */ \"updateStatus\": () => (/* binding */ updateStatus)\n/* harmony export */ });\n/* harmony import */ var _store_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./store.js */ \"./src/modules/store.js\");\n/* harmony import */ var _UI_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./UI.js */ \"./src/modules/UI.js\");\n\r\n\r\n\r\nconst updateStatus = (id) => {\r\n const [statusId] = id.match(/\\d+/);\r\n const todos = (0,_store_js__WEBPACK_IMPORTED_MODULE_0__.getTodos)().map((todo) => {\r\n if (todo.id === statusId) {\r\n return { ...todo, completed: !todo.completed };\r\n }\r\n return todo;\r\n });\r\n (0,_store_js__WEBPACK_IMPORTED_MODULE_0__.setTodos)(todos);\r\n};\r\nconst clearTodoList = () => {\r\n const listToNotClear = (0,_store_js__WEBPACK_IMPORTED_MODULE_0__.getTodos)()\r\n .filter((todo) => todo.completed === false)\r\n .map((todo, index) => ({ ...todo, index: index + 1 }));\r\n const listToClear = (0,_store_js__WEBPACK_IMPORTED_MODULE_0__.getTodos)().filter((todo) => todo.completed === true);\r\n\r\n listToClear.forEach((todo) => {\r\n _UI_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"].remove(todo.id);\r\n });\r\n (0,_store_js__WEBPACK_IMPORTED_MODULE_0__.setTodos)(listToNotClear);\r\n};\r\n\n\n//# sourceURL=webpack://to-do-list/./src/modules/updateStatus.js?"); 170 | 171 | /***/ }) 172 | 173 | /******/ }); 174 | /************************************************************************/ 175 | /******/ // The module cache 176 | /******/ var __webpack_module_cache__ = {}; 177 | /******/ 178 | /******/ // The require function 179 | /******/ function __webpack_require__(moduleId) { 180 | /******/ // Check if module is in cache 181 | /******/ var cachedModule = __webpack_module_cache__[moduleId]; 182 | /******/ if (cachedModule !== undefined) { 183 | /******/ return cachedModule.exports; 184 | /******/ } 185 | /******/ // Create a new module (and put it into the cache) 186 | /******/ var module = __webpack_module_cache__[moduleId] = { 187 | /******/ id: moduleId, 188 | /******/ // no module.loaded needed 189 | /******/ exports: {} 190 | /******/ }; 191 | /******/ 192 | /******/ // Execute the module function 193 | /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); 194 | /******/ 195 | /******/ // Return the exports of the module 196 | /******/ return module.exports; 197 | /******/ } 198 | /******/ 199 | /************************************************************************/ 200 | /******/ /* webpack/runtime/compat get default export */ 201 | /******/ (() => { 202 | /******/ // getDefaultExport function for compatibility with non-harmony modules 203 | /******/ __webpack_require__.n = (module) => { 204 | /******/ var getter = module && module.__esModule ? 205 | /******/ () => (module['default']) : 206 | /******/ () => (module); 207 | /******/ __webpack_require__.d(getter, { a: getter }); 208 | /******/ return getter; 209 | /******/ }; 210 | /******/ })(); 211 | /******/ 212 | /******/ /* webpack/runtime/define property getters */ 213 | /******/ (() => { 214 | /******/ // define getter functions for harmony exports 215 | /******/ __webpack_require__.d = (exports, definition) => { 216 | /******/ for(var key in definition) { 217 | /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 218 | /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 219 | /******/ } 220 | /******/ } 221 | /******/ }; 222 | /******/ })(); 223 | /******/ 224 | /******/ /* webpack/runtime/hasOwnProperty shorthand */ 225 | /******/ (() => { 226 | /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) 227 | /******/ })(); 228 | /******/ 229 | /******/ /* webpack/runtime/make namespace object */ 230 | /******/ (() => { 231 | /******/ // define __esModule on exports 232 | /******/ __webpack_require__.r = (exports) => { 233 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 234 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 235 | /******/ } 236 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 237 | /******/ }; 238 | /******/ })(); 239 | /******/ 240 | /******/ /* webpack/runtime/nonce */ 241 | /******/ (() => { 242 | /******/ __webpack_require__.nc = undefined; 243 | /******/ })(); 244 | /******/ 245 | /************************************************************************/ 246 | /******/ 247 | /******/ // startup 248 | /******/ // Load entry module and return exports 249 | /******/ // This entry module can't be inlined because the eval devtool is used. 250 | /******/ var __webpack_exports__ = __webpack_require__("./src/index.js"); 251 | /******/ 252 | /******/ })() 253 | ; --------------------------------------------------------------------------------