├── .babelrc ├── .eslintrc.json ├── .github └── workflows │ └── linters.yml ├── .gitignore ├── .hintrc ├── .stylelintrc.json ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── dist ├── index.html ├── main.js └── runtime.js ├── package-lock.json ├── package.json ├── src ├── index.html ├── index.js ├── modules │ ├── addTodoItem.js │ ├── deleteTodo.js │ ├── handleCompleted.js │ └── storeTodo.js └── style.css └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "test": { 4 | "plugins": ["@babel/plugin-transform-modules-commonjs"] 5 | } 6 | } 7 | } -------------------------------------------------------------------------------- /.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": [ 1, { 18 | "js": "always", "json": "always" 19 | }] 20 | }, 21 | "ignorePatterns": [ 22 | "dist/", 23 | "build/" 24 | ] 25 | } -------------------------------------------------------------------------------- /.github/workflows/linters.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 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /.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 | } -------------------------------------------------------------------------------- /.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": ["tailwind", "apply", "variants", "responsive", "screen"] 9 | } 10 | ], 11 | "scss/at-rule-no-unknown": [ 12 | true, 13 | { 14 | "ignoreAtRules": ["tailwind", "apply", "variants", "responsive", "screen"] 15 | } 16 | ], 17 | "csstree/validator": true 18 | }, 19 | "ignoreFiles": ["build/**", "dist/**", "**/reset*.css", "**/bootstrap*.css", "**/*.js", "**/*.jsx"] 20 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "liveServer.settings.port": 5501 3 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Theophilus 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 📗 Table of Contents 4 | 5 | - [📖 About the Project](#about-project) 6 | - [🛠 Built With](#built-with) 7 | - [Key Features](#key-features) 8 | - [🚀 Live Demo](#live-demo) 9 | - [📹 Video Walkthrough](#video-walkthrough) 10 | - [💻 Getting Started](#getting-started) 11 | - [Prerequisites](#prerequisites) 12 | - [Setup](#setup) 13 | - [👥 Authors](#authors) 14 | - [🔭 Future Features](#future-features) 15 | - [🤝 Contributing](#contributing) 16 | - [⭐️ Show your support](#support) 17 | - [🙏 Acknowledgements](#acknowledgements) 18 | - [📝 License](#license) 19 | 20 | 21 | 22 | # 📖 ToDo-List 23 | 24 | > To build a simple HTML list of To Do tasks. 25 | 26 | **Todo-List** This is a simple To Do App that allows users to keep track of their tasks and remove them when they have completed each task. It was built using HTML, CSS and JavaScript. 27 | 28 | 29 | 30 | ## 🛠 Built With 31 | 32 | - **HTML5** 33 | - **CSS3** 34 | - **Webpack** 35 | - **JavaScript** 36 | 37 |

(back to top)

38 | 39 | 40 | 41 | ### Key Features 42 | 43 | - **Adding a new item** 44 | - **Removing a selected item** 45 | - **Add a new JavaScript file and import it as a module for the status updates (completed: true / false).** 46 | - **Add event listener to the checkbox (change).** 47 | - **Update items object's value for completed key upon user actions.** 48 | - **Implement a function for the "Clear all completed" button (use filter() method)** 49 |

(back to top)

50 | 51 | 52 | 53 | ## 🚀 Live Demo 54 | 55 | > Link to deployed project. 56 | 57 | - [https://theodoku.github.io/todo-List/dist/] 58 | 59 |

(back to top)

60 | 61 | 62 | 63 | ## 📹 Video Walkthrough 64 | 65 | > Link to video presentation. 66 | 67 | - [coming soon] 68 | 69 |

(back to top)

70 | 71 | 72 | 73 | ## 💻 Getting Started 74 | 75 | To get a local copy up and running, follow these steps. 76 | 77 | ### Prerequisites 78 | 79 | In order to run this project you need: 80 | 81 | - Git and Code editor of your choice. 82 | 83 | ### Setup 84 | 85 | Clone this repository to your desired folder: 86 | 87 | 1. Use VScode: open terminal in VScode 88 | 2. Navigate to the directory where you want clone the copy of this repository 89 | 3. Create new directory [optional] 90 | 4. Clone the repo using the below command 91 | 92 | **`git clone https://github.com/theodoku/todo-List`** 93 | 94 |

(back to top)

95 | 96 | 97 | 98 | ## 👥 Authors 99 | 100 | 👤 **theodoku** 101 | 102 | - GitHub: [@githubhandle](https://github.com/theodoku) 103 | - Twitter: [@twitterhandle](https://twitter.com/dok_theo) 104 | - LinkedIn: [LinkedIn](https://linkedin.com/in/Theophilusdoku) 105 | 106 |

(back to top)

107 | 108 | 109 | 110 | ## 🔭 Future Features 111 | 112 | - [Marking a selected item as complete] 113 | - [Removing all items marked as complete at once] 114 | - [Reordering a selected item (as drag-and-drop)] 115 | 116 |

(back to top)

117 | 118 | 119 | 120 | ## 🤝 Contributing 121 | 122 | Contributions, issues, and feature requests are welcome! 123 | 124 | Feel free to check the [issues page](https://github.com/theodoku/todo-List/issues). 125 | 126 |

(back to top)

127 | 128 | 129 | 130 | ## ⭐️ Show your support 131 | 132 | > If you like this project please give a ⭐️ to this repository, and follow me on GitHub & LinkedIn. 133 | 134 |

(back to top)

135 | 136 | 137 | 138 | ## 🙏 Acknowledgments 139 | 140 | > I would like to thank [Microverseinc](https://github.com/microverseinc). 141 | 142 | - minimalist captured project https://web.archive.org/web/20180320194056/http://www.getminimalist.com:80/👍 143 | 144 |

(back to top)

145 | 146 | 147 | 148 | ## 📝 License 149 | 150 | This project is [MIT](./LICENSE) licensed. 151 | 152 |

(back to top)

153 | -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | To Do List 8 | 12 | 13 | 14 |
15 |
16 |

Today's To Do

17 | 18 | 21 | 22 |
23 |
24 |
25 |
26 | 27 | 34 |
35 |
36 |
37 |
38 | 39 |
40 |
41 |

Clear all completed

42 |
43 |
44 | 45 | 46 | -------------------------------------------------------------------------------- /dist/main.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /* 3 | * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development"). 4 | * This devtool is neither made for production nor for readable output files. 5 | * It uses "eval()" calls to create a separate source file in the browser devtools. 6 | * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) 7 | * or disable the default devtool with "devtool: false". 8 | * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). 9 | */ 10 | (self["webpackChunkwebpack_setup"] = self["webpackChunkwebpack_setup"] || []).push([["main"],{ 11 | 12 | /***/ "./node_modules/css-loader/dist/cjs.js!./src/style.css": 13 | /*!*************************************************************!*\ 14 | !*** ./node_modules/css-loader/dist/cjs.js!./src/style.css ***! 15 | \*************************************************************/ 16 | /***/ ((module, __webpack_exports__, __webpack_require__) => { 17 | 18 | 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, \"body {\\r\\n padding: 0;\\r\\n margin: 0;\\r\\n box-sizing: border-box;\\r\\n}\\r\\n\\r\\n.main {\\r\\n width: 40%;\\r\\n margin: 100px auto;\\r\\n box-shadow: rgba(0, 0, 0, 0.24) 0 3px 8px;\\r\\n}\\r\\n\\r\\n#title {\\r\\n font-size: 20px;\\r\\n margin: 0;\\r\\n color: #9a9ca2;\\r\\n}\\r\\n\\r\\ninput {\\r\\n width: 100%;\\r\\n border: none;\\r\\n height: 50px;\\r\\n font-style: italic;\\r\\n}\\r\\n\\r\\ninput:focus {\\r\\n outline: none;\\r\\n}\\r\\n\\r\\ninput[type='checkbox'] {\\r\\n margin-right: 10px;\\r\\n}\\r\\n\\r\\ninput[type='checkbox']:checked + input {\\r\\n text-decoration: line-through;\\r\\n color: #cacacb;\\r\\n}\\r\\n\\r\\n.header {\\r\\n display: flex;\\r\\n justify-content: space-between;\\r\\n align-items: center;\\r\\n padding: 10px;\\r\\n}\\r\\n\\r\\n.todo_form {\\r\\n border-bottom: 1px solid #f4f5f4;\\r\\n padding: 15px;\\r\\n}\\r\\n\\r\\n.todo_wrapper {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n}\\r\\n\\r\\n.btn {\\r\\n border: none;\\r\\n background: none;\\r\\n outline: none;\\r\\n width: 25px;\\r\\n}\\r\\n\\r\\n.clear {\\r\\n text-align: center;\\r\\n background-color: #f6f6f6;\\r\\n cursor: pointer;\\r\\n}\\r\\n\\r\\n.clearText {\\r\\n margin: 0;\\r\\n padding: 15px;\\r\\n color: #cacacb;\\r\\n}\\r\\n\\r\\n.desciption {\\r\\n width: 100%;\\r\\n}\\r\\n\\r\\n#lists {\\r\\n padding: 0;\\r\\n margin: 0;\\r\\n list-style: none;\\r\\n}\\r\\n\\r\\n.listTask {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n justify-content: space-between;\\r\\n border-bottom: 1px solid #f4f5f4;\\r\\n padding: 10px;\\r\\n}\\r\\n\\r\\n.listTaskWrapper {\\r\\n display: flex;\\r\\n align-items: center;\\r\\n gap: 10px;\\r\\n}\\r\\n\\r\\n#checkbox {\\r\\n width: 15px;\\r\\n border-color: #c0c0c3;\\r\\n}\\r\\n\\r\\n.todoBtn {\\r\\n border: none;\\r\\n background-color: white;\\r\\n outline: none;\\r\\n cursor: pointer;\\r\\n}\\r\\n\", \"\"]);\n// Exports\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://webpack-setup/./src/style.css?./node_modules/css-loader/dist/cjs.js"); 19 | 20 | /***/ }), 21 | 22 | /***/ "./node_modules/css-loader/dist/runtime/api.js": 23 | /*!*****************************************************!*\ 24 | !*** ./node_modules/css-loader/dist/runtime/api.js ***! 25 | \*****************************************************/ 26 | /***/ ((module) => { 27 | 28 | 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://webpack-setup/./node_modules/css-loader/dist/runtime/api.js?"); 29 | 30 | /***/ }), 31 | 32 | /***/ "./node_modules/css-loader/dist/runtime/noSourceMaps.js": 33 | /*!**************************************************************!*\ 34 | !*** ./node_modules/css-loader/dist/runtime/noSourceMaps.js ***! 35 | \**************************************************************/ 36 | /***/ ((module) => { 37 | 38 | eval("\n\nmodule.exports = function (i) {\n return i[1];\n};\n\n//# sourceURL=webpack://webpack-setup/./node_modules/css-loader/dist/runtime/noSourceMaps.js?"); 39 | 40 | /***/ }), 41 | 42 | /***/ "./src/style.css": 43 | /*!***********************!*\ 44 | !*** ./src/style.css ***! 45 | \***********************/ 46 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 47 | 48 | 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://webpack-setup/./src/style.css?"); 49 | 50 | /***/ }), 51 | 52 | /***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js": 53 | /*!****************************************************************************!*\ 54 | !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***! 55 | \****************************************************************************/ 56 | /***/ ((module) => { 57 | 58 | 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://webpack-setup/./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js?"); 59 | 60 | /***/ }), 61 | 62 | /***/ "./node_modules/style-loader/dist/runtime/insertBySelector.js": 63 | /*!********************************************************************!*\ 64 | !*** ./node_modules/style-loader/dist/runtime/insertBySelector.js ***! 65 | \********************************************************************/ 66 | /***/ ((module) => { 67 | 68 | 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://webpack-setup/./node_modules/style-loader/dist/runtime/insertBySelector.js?"); 69 | 70 | /***/ }), 71 | 72 | /***/ "./node_modules/style-loader/dist/runtime/insertStyleElement.js": 73 | /*!**********************************************************************!*\ 74 | !*** ./node_modules/style-loader/dist/runtime/insertStyleElement.js ***! 75 | \**********************************************************************/ 76 | /***/ ((module) => { 77 | 78 | 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://webpack-setup/./node_modules/style-loader/dist/runtime/insertStyleElement.js?"); 79 | 80 | /***/ }), 81 | 82 | /***/ "./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js": 83 | /*!**********************************************************************************!*\ 84 | !*** ./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js ***! 85 | \**********************************************************************************/ 86 | /***/ ((module, __unused_webpack_exports, __webpack_require__) => { 87 | 88 | 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://webpack-setup/./node_modules/style-loader/dist/runtime/setAttributesWithoutAttributes.js?"); 89 | 90 | /***/ }), 91 | 92 | /***/ "./node_modules/style-loader/dist/runtime/styleDomAPI.js": 93 | /*!***************************************************************!*\ 94 | !*** ./node_modules/style-loader/dist/runtime/styleDomAPI.js ***! 95 | \***************************************************************/ 96 | /***/ ((module) => { 97 | 98 | 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://webpack-setup/./node_modules/style-loader/dist/runtime/styleDomAPI.js?"); 99 | 100 | /***/ }), 101 | 102 | /***/ "./node_modules/style-loader/dist/runtime/styleTagTransform.js": 103 | /*!*********************************************************************!*\ 104 | !*** ./node_modules/style-loader/dist/runtime/styleTagTransform.js ***! 105 | \*********************************************************************/ 106 | /***/ ((module) => { 107 | 108 | 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://webpack-setup/./node_modules/style-loader/dist/runtime/styleTagTransform.js?"); 109 | 110 | /***/ }), 111 | 112 | /***/ "./src/index.js": 113 | /*!**********************!*\ 114 | !*** ./src/index.js ***! 115 | \**********************/ 116 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 117 | 118 | 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_addTodoItem_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./modules/addTodoItem.js */ \"./src/modules/addTodoItem.js\");\n/* harmony import */ var _modules_deleteTodo_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./modules/deleteTodo.js */ \"./src/modules/deleteTodo.js\");\n/* harmony import */ var _modules_handleCompleted_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./modules/handleCompleted.js */ \"./src/modules/handleCompleted.js\");\n/* harmony import */ var _modules_storeTodo_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./modules/storeTodo.js */ \"./src/modules/storeTodo.js\");\n\r\n\r\n\r\n\r\n\r\n\r\nconst display = () => {\r\n const todos = (0,_modules_storeTodo_js__WEBPACK_IMPORTED_MODULE_4__.getTodo)() || [];\r\n if (todos) {\r\n todos.map((todo) => (0,_modules_addTodoItem_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(todo));\r\n }\r\n};\r\n\r\ndisplay();\r\ndocument.getElementById('form').addEventListener('submit', (e) => {\r\n e.preventDefault();\r\n const todos = (0,_modules_storeTodo_js__WEBPACK_IMPORTED_MODULE_4__.getTodo)();\r\n const todoInput = document.getElementById('task').value;\r\n const todoTask = {\r\n index: todos.length,\r\n description: todoInput,\r\n completed: false,\r\n };\r\n\r\n if (todoInput !== '') {\r\n (0,_modules_addTodoItem_js__WEBPACK_IMPORTED_MODULE_1__[\"default\"])(todoTask);\r\n (0,_modules_storeTodo_js__WEBPACK_IMPORTED_MODULE_4__.addTodo)(todoTask);\r\n document.getElementById('form').reset();\r\n }\r\n});\r\n\r\nconst inputField = document.querySelectorAll('.description');\r\n\r\ninputField.forEach((todo, index) => {\r\n todo.addEventListener('change', (e) => {\r\n const updateInput = e.target.value;\r\n const todos = (0,_modules_storeTodo_js__WEBPACK_IMPORTED_MODULE_4__.getTodo)();\r\n todos[index].description = updateInput;\r\n (0,_modules_storeTodo_js__WEBPACK_IMPORTED_MODULE_4__.updateTodo)(index, todos[index].description);\r\n window.location.reload();\r\n });\r\n});\r\ninputField.forEach((todo, index) => {\r\n todo.addEventListener('keypress', (e) => {\r\n if (e.key === 'Enter') {\r\n const updateInput = e.target.value;\r\n const todos = (0,_modules_storeTodo_js__WEBPACK_IMPORTED_MODULE_4__.getTodo)();\r\n todos[index].desciption = updateInput;\r\n (0,_modules_storeTodo_js__WEBPACK_IMPORTED_MODULE_4__.updateTodo)(index, todos[index].description);\r\n window.location.reload();\r\n }\r\n });\r\n});\r\n\r\nwindow.remove = (index) => {\r\n (0,_modules_deleteTodo_js__WEBPACK_IMPORTED_MODULE_2__[\"default\"])(index);\r\n (0,_modules_storeTodo_js__WEBPACK_IMPORTED_MODULE_4__.removeTodo)(index);\r\n};\r\n\r\nwindow.completedTodo = (index) => {\r\n (0,_modules_handleCompleted_js__WEBPACK_IMPORTED_MODULE_3__[\"default\"])(index);\r\n};\r\n\r\ndocument.getElementById('allCompleted').addEventListener('click', () => {\r\n const todos = (0,_modules_storeTodo_js__WEBPACK_IMPORTED_MODULE_4__.getTodo)();\r\n const allCompleted = todos.filter((todo) => !todo.completed);\r\n allCompleted.forEach((todo, i) => {\r\n todo.index = i;\r\n });\r\n localStorage.setItem('todos', JSON.stringify(allCompleted));\r\n window.location.reload();\r\n});\r\n\n\n//# sourceURL=webpack://webpack-setup/./src/index.js?"); 119 | 120 | /***/ }), 121 | 122 | /***/ "./src/modules/addTodoItem.js": 123 | /*!************************************!*\ 124 | !*** ./src/modules/addTodoItem.js ***! 125 | \************************************/ 126 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 127 | 128 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nfunction checkbox() {\r\n const checkboxes = document.querySelectorAll('input[type=checkbox]');\r\n const description = document.querySelectorAll('.edit');\r\n checkboxes.forEach((cb, i) => {\r\n cb.addEventListener('change', () => {\r\n if (checkboxes[i].checked) {\r\n description[i].style.textDecoration = 'line-through';\r\n description[i].style.color = '#cacacb';\r\n } else {\r\n description[i].style.textDecoration = 'none';\r\n description[i].style.color = 'black';\r\n }\r\n });\r\n });\r\n}\r\n\r\nconst list = document.getElementById('lists');\r\nconst addTodoItem = (todo) => {\r\n list.innerHTML += `\r\n
  • \r\n
    \r\n \r\n \r\n
  • \r\n `;\r\n checkbox();\r\n};\r\n\r\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (addTodoItem);\r\n\n\n//# sourceURL=webpack://webpack-setup/./src/modules/addTodoItem.js?"); 129 | 130 | /***/ }), 131 | 132 | /***/ "./src/modules/deleteTodo.js": 133 | /*!***********************************!*\ 134 | !*** ./src/modules/deleteTodo.js ***! 135 | \***********************************/ 136 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 137 | 138 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\nconst deleteTodo = (index) => {\n const todoIndex = document.getElementById(`todo${index}`);\n if (todoIndex !== null) {\n todoIndex.remove();\n }\n};\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (deleteTodo);\n\n//# sourceURL=webpack://webpack-setup/./src/modules/deleteTodo.js?"); 139 | 140 | /***/ }), 141 | 142 | /***/ "./src/modules/handleCompleted.js": 143 | /*!****************************************!*\ 144 | !*** ./src/modules/handleCompleted.js ***! 145 | \****************************************/ 146 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 147 | 148 | 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 _storeTodo_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./storeTodo.js */ \"./src/modules/storeTodo.js\");\n\r\n\r\nconst handleCompleted = (index) => {\r\n const completed = document.getElementById(`check${index}`).toggleAttribute('checked');\r\n const todos = (0,_storeTodo_js__WEBPACK_IMPORTED_MODULE_0__.getTodo)();\r\n\r\n todos[index].completed = completed;\r\n localStorage.setItem('todos', JSON.stringify(todos));\r\n};\r\n\r\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (handleCompleted);\n\n//# sourceURL=webpack://webpack-setup/./src/modules/handleCompleted.js?"); 149 | 150 | /***/ }), 151 | 152 | /***/ "./src/modules/storeTodo.js": 153 | /*!**********************************!*\ 154 | !*** ./src/modules/storeTodo.js ***! 155 | \**********************************/ 156 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 157 | 158 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"addTodo\": () => (/* binding */ addTodo),\n/* harmony export */ \"getTodo\": () => (/* binding */ getTodo),\n/* harmony export */ \"removeTodo\": () => (/* binding */ removeTodo),\n/* harmony export */ \"updateTodo\": () => (/* binding */ updateTodo)\n/* harmony export */ });\nconst getTodo = () => {\n let todos;\n if (localStorage.getItem('todos') === null) {\n todos = [];\n } else {\n todos = JSON.parse(localStorage.getItem('todos'));\n }\n return todos;\n};\n\nconst addTodo = (todo) => {\n const todos = getTodo();\n todos.push(todo);\n localStorage.setItem('todos', JSON.stringify(todos));\n};\n\nconst removeTodo = (index) => {\n const todos = getTodo();\n const deletedTodos = todos.filter((todo) => todo.index !== index);\n deletedTodos.forEach((todo, i) => {\n todo.index = i;\n });\n localStorage.setItem('todos', JSON.stringify(deletedTodos));\n window.location.reload();\n};\n\nconst updateTodo = (index, description) => {\n const todos = getTodo();\n const todo = todos.find((todoTask) => todoTask.index === index);\n todo.description = description;\n localStorage.setItem('todos', JSON.stringify(todos));\n};\n\n\n\n//# sourceURL=webpack://webpack-setup/./src/modules/storeTodo.js?"); 159 | 160 | /***/ }) 161 | 162 | }, 163 | /******/ __webpack_require__ => { // webpackRuntimeModules 164 | /******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId)) 165 | /******/ var __webpack_exports__ = (__webpack_exec__("./src/index.js")); 166 | /******/ } 167 | ]); -------------------------------------------------------------------------------- /dist/runtime.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 | /******/ // The module cache 14 | /******/ var __webpack_module_cache__ = {}; 15 | /******/ 16 | /******/ // The require function 17 | /******/ function __webpack_require__(moduleId) { 18 | /******/ // Check if module is in cache 19 | /******/ var cachedModule = __webpack_module_cache__[moduleId]; 20 | /******/ if (cachedModule !== undefined) { 21 | /******/ return cachedModule.exports; 22 | /******/ } 23 | /******/ // Create a new module (and put it into the cache) 24 | /******/ var module = __webpack_module_cache__[moduleId] = { 25 | /******/ id: moduleId, 26 | /******/ // no module.loaded needed 27 | /******/ exports: {} 28 | /******/ }; 29 | /******/ 30 | /******/ // Execute the module function 31 | /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); 32 | /******/ 33 | /******/ // Return the exports of the module 34 | /******/ return module.exports; 35 | /******/ } 36 | /******/ 37 | /******/ // expose the modules object (__webpack_modules__) 38 | /******/ __webpack_require__.m = __webpack_modules__; 39 | /******/ 40 | /************************************************************************/ 41 | /******/ /* webpack/runtime/chunk loaded */ 42 | /******/ (() => { 43 | /******/ var deferred = []; 44 | /******/ __webpack_require__.O = (result, chunkIds, fn, priority) => { 45 | /******/ if(chunkIds) { 46 | /******/ priority = priority || 0; 47 | /******/ for(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1]; 48 | /******/ deferred[i] = [chunkIds, fn, priority]; 49 | /******/ return; 50 | /******/ } 51 | /******/ var notFulfilled = Infinity; 52 | /******/ for (var i = 0; i < deferred.length; i++) { 53 | /******/ var [chunkIds, fn, priority] = deferred[i]; 54 | /******/ var fulfilled = true; 55 | /******/ for (var j = 0; j < chunkIds.length; j++) { 56 | /******/ if ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) { 57 | /******/ chunkIds.splice(j--, 1); 58 | /******/ } else { 59 | /******/ fulfilled = false; 60 | /******/ if(priority < notFulfilled) notFulfilled = priority; 61 | /******/ } 62 | /******/ } 63 | /******/ if(fulfilled) { 64 | /******/ deferred.splice(i--, 1) 65 | /******/ var r = fn(); 66 | /******/ if (r !== undefined) result = r; 67 | /******/ } 68 | /******/ } 69 | /******/ return result; 70 | /******/ }; 71 | /******/ })(); 72 | /******/ 73 | /******/ /* webpack/runtime/compat get default export */ 74 | /******/ (() => { 75 | /******/ // getDefaultExport function for compatibility with non-harmony modules 76 | /******/ __webpack_require__.n = (module) => { 77 | /******/ var getter = module && module.__esModule ? 78 | /******/ () => (module['default']) : 79 | /******/ () => (module); 80 | /******/ __webpack_require__.d(getter, { a: getter }); 81 | /******/ return getter; 82 | /******/ }; 83 | /******/ })(); 84 | /******/ 85 | /******/ /* webpack/runtime/define property getters */ 86 | /******/ (() => { 87 | /******/ // define getter functions for harmony exports 88 | /******/ __webpack_require__.d = (exports, definition) => { 89 | /******/ for(var key in definition) { 90 | /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 91 | /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 92 | /******/ } 93 | /******/ } 94 | /******/ }; 95 | /******/ })(); 96 | /******/ 97 | /******/ /* webpack/runtime/hasOwnProperty shorthand */ 98 | /******/ (() => { 99 | /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) 100 | /******/ })(); 101 | /******/ 102 | /******/ /* webpack/runtime/make namespace object */ 103 | /******/ (() => { 104 | /******/ // define __esModule on exports 105 | /******/ __webpack_require__.r = (exports) => { 106 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 107 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 108 | /******/ } 109 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 110 | /******/ }; 111 | /******/ })(); 112 | /******/ 113 | /******/ /* webpack/runtime/jsonp chunk loading */ 114 | /******/ (() => { 115 | /******/ // no baseURI 116 | /******/ 117 | /******/ // object to store loaded and loading chunks 118 | /******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched 119 | /******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded 120 | /******/ var installedChunks = { 121 | /******/ "runtime": 0 122 | /******/ }; 123 | /******/ 124 | /******/ // no chunk on demand loading 125 | /******/ 126 | /******/ // no prefetching 127 | /******/ 128 | /******/ // no preloaded 129 | /******/ 130 | /******/ // no HMR 131 | /******/ 132 | /******/ // no HMR manifest 133 | /******/ 134 | /******/ __webpack_require__.O.j = (chunkId) => (installedChunks[chunkId] === 0); 135 | /******/ 136 | /******/ // install a JSONP callback for chunk loading 137 | /******/ var webpackJsonpCallback = (parentChunkLoadingFunction, data) => { 138 | /******/ var [chunkIds, moreModules, runtime] = data; 139 | /******/ // add "moreModules" to the modules object, 140 | /******/ // then flag all "chunkIds" as loaded and fire callback 141 | /******/ var moduleId, chunkId, i = 0; 142 | /******/ if(chunkIds.some((id) => (installedChunks[id] !== 0))) { 143 | /******/ for(moduleId in moreModules) { 144 | /******/ if(__webpack_require__.o(moreModules, moduleId)) { 145 | /******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; 146 | /******/ } 147 | /******/ } 148 | /******/ if(runtime) var result = runtime(__webpack_require__); 149 | /******/ } 150 | /******/ if(parentChunkLoadingFunction) parentChunkLoadingFunction(data); 151 | /******/ for(;i < chunkIds.length; i++) { 152 | /******/ chunkId = chunkIds[i]; 153 | /******/ if(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { 154 | /******/ installedChunks[chunkId][0](); 155 | /******/ } 156 | /******/ installedChunks[chunkId] = 0; 157 | /******/ } 158 | /******/ return __webpack_require__.O(result); 159 | /******/ } 160 | /******/ 161 | /******/ var chunkLoadingGlobal = self["webpackChunkwebpack_setup"] = self["webpackChunkwebpack_setup"] || []; 162 | /******/ chunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0)); 163 | /******/ chunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal)); 164 | /******/ })(); 165 | /******/ 166 | /******/ /* webpack/runtime/nonce */ 167 | /******/ (() => { 168 | /******/ __webpack_require__.nc = undefined; 169 | /******/ })(); 170 | /******/ 171 | /************************************************************************/ 172 | /******/ 173 | /******/ 174 | /******/ })() 175 | ; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webpack-setup", 3 | "version": "1.0.0", 4 | "description": "A boilerplate to be used in my future projects.", 5 | "private": true, 6 | "scripts": { 7 | "test": "jest --coverage", 8 | "start": "webpack-dev-server --open", 9 | "build": "webpack", 10 | "deploy": "gh-pages -d dist" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/theodoku/Webpack-Setup.git" 15 | }, 16 | "keywords": [], 17 | "author": "theodoku", 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/theodoku/Webpack-Setup/issues" 21 | }, 22 | "homepage": "https://github.com/theodoku/Webpack-Setup#readme", 23 | "devDependencies": { 24 | "@babel/plugin-transform-modules-commonjs": "^7.21.2", 25 | "babel-eslint": "^10.1.0", 26 | "css-loader": "^6.7.3", 27 | "eslint": "^7.32.0", 28 | "eslint-config-airbnb-base": "^14.2.1", 29 | "eslint-plugin-html": "^7.1.0", 30 | "eslint-plugin-import": "^2.27.5", 31 | "hint": "^7.1.3", 32 | "html-webpack-plugin": "^5.5.0", 33 | "jest": "^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 | "svg-inline-loader": "^0.8.2", 40 | "webpack": "^5.75.0", 41 | "webpack-cli": "^5.0.1", 42 | "webpack-dev-server": "^4.11.1" 43 | }, 44 | "dependencies": { 45 | "eslint-import-resolver-webpack": "^0.13.2", 46 | "jsdom": "^21.1.0", 47 | "lodash": "^4.17.21" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | To Do List 8 | 12 | 13 | 14 |
    15 |
    16 |

    Today's To Do

    17 | 18 | 21 | 22 |
    23 |
    24 |
    25 |
    26 | 27 | 34 |
    35 |
    36 |
    37 |
    38 | 39 |
    40 |
    41 |

    Clear all completed

    42 |
    43 |
    44 | 45 | 46 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import './style.css'; 2 | import addTodoItem from './modules/addTodoItem.js'; 3 | import deleteTodo from './modules/deleteTodo.js'; 4 | import handleCompleted from './modules/handleCompleted.js'; 5 | import { 6 | addTodo, getTodo, removeTodo, updateTodo, 7 | } from './modules/storeTodo.js'; 8 | 9 | const display = () => { 10 | const todos = getTodo() || []; 11 | if (todos) { 12 | todos.map((todo) => addTodoItem(todo)); 13 | } 14 | }; 15 | 16 | display(); 17 | document.getElementById('form').addEventListener('submit', (e) => { 18 | e.preventDefault(); 19 | const todos = getTodo(); 20 | const todoInput = document.getElementById('task').value; 21 | const todoTask = { 22 | index: todos.length, 23 | description: todoInput, 24 | completed: false, 25 | }; 26 | 27 | if (todoInput !== '') { 28 | addTodoItem(todoTask); 29 | addTodo(todoTask); 30 | document.getElementById('form').reset(); 31 | } 32 | }); 33 | 34 | const inputField = document.querySelectorAll('.description'); 35 | 36 | inputField.forEach((todo, index) => { 37 | todo.addEventListener('change', (e) => { 38 | const updateInput = e.target.value; 39 | const todos = getTodo(); 40 | todos[index].description = updateInput; 41 | updateTodo(index, todos[index].description); 42 | window.location.reload(); 43 | }); 44 | }); 45 | inputField.forEach((todo, index) => { 46 | todo.addEventListener('keypress', (e) => { 47 | if (e.key === 'Enter') { 48 | const updateInput = e.target.value; 49 | const todos = getTodo(); 50 | todos[index].desciption = updateInput; 51 | updateTodo(index, todos[index].description); 52 | window.location.reload(); 53 | } 54 | }); 55 | }); 56 | 57 | window.remove = (index) => { 58 | deleteTodo(index); 59 | removeTodo(index); 60 | }; 61 | 62 | window.completedTodo = (index) => { 63 | handleCompleted(index); 64 | }; 65 | 66 | document.getElementById('allCompleted').addEventListener('click', () => { 67 | const todos = getTodo(); 68 | const allCompleted = todos.filter((todo) => !todo.completed); 69 | allCompleted.forEach((todo, i) => { 70 | todo.index = i; 71 | }); 72 | localStorage.setItem('todos', JSON.stringify(allCompleted)); 73 | window.location.reload(); 74 | }); 75 | -------------------------------------------------------------------------------- /src/modules/addTodoItem.js: -------------------------------------------------------------------------------- 1 | function checkbox() { 2 | const checkboxes = document.querySelectorAll('input[type=checkbox]'); 3 | const description = document.querySelectorAll('.edit'); 4 | checkboxes.forEach((cb, i) => { 5 | cb.addEventListener('change', () => { 6 | if (checkboxes[i].checked) { 7 | description[i].style.textDecoration = 'line-through'; 8 | description[i].style.color = '#cacacb'; 9 | } else { 10 | description[i].style.textDecoration = 'none'; 11 | description[i].style.color = 'black'; 12 | } 13 | }); 14 | }); 15 | } 16 | 17 | const list = document.getElementById('lists'); 18 | const addTodoItem = (todo) => { 19 | list.innerHTML += ` 20 |
  • 21 |
    22 | 23 | 26 |
  • 27 | `; 28 | checkbox(); 29 | }; 30 | 31 | export default addTodoItem; 32 | -------------------------------------------------------------------------------- /src/modules/deleteTodo.js: -------------------------------------------------------------------------------- 1 | const deleteTodo = (index) => { 2 | const todoIndex = document.getElementById(`todo${index}`); 3 | if (todoIndex !== null) { 4 | todoIndex.remove(); 5 | } 6 | }; 7 | 8 | export default deleteTodo; -------------------------------------------------------------------------------- /src/modules/handleCompleted.js: -------------------------------------------------------------------------------- 1 | import { getTodo } from './storeTodo.js'; 2 | 3 | const handleCompleted = (index) => { 4 | const completed = document.getElementById(`check${index}`).toggleAttribute('checked'); 5 | const todos = getTodo(); 6 | 7 | todos[index].completed = completed; 8 | localStorage.setItem('todos', JSON.stringify(todos)); 9 | }; 10 | 11 | export default handleCompleted; -------------------------------------------------------------------------------- /src/modules/storeTodo.js: -------------------------------------------------------------------------------- 1 | const getTodo = () => { 2 | let todos; 3 | if (localStorage.getItem('todos') === null) { 4 | todos = []; 5 | } else { 6 | todos = JSON.parse(localStorage.getItem('todos')); 7 | } 8 | return todos; 9 | }; 10 | 11 | const addTodo = (todo) => { 12 | const todos = getTodo(); 13 | todos.push(todo); 14 | localStorage.setItem('todos', JSON.stringify(todos)); 15 | }; 16 | 17 | const removeTodo = (index) => { 18 | const todos = getTodo(); 19 | const deletedTodos = todos.filter((todo) => todo.index !== index); 20 | deletedTodos.forEach((todo, i) => { 21 | todo.index = i; 22 | }); 23 | localStorage.setItem('todos', JSON.stringify(deletedTodos)); 24 | window.location.reload(); 25 | }; 26 | 27 | const updateTodo = (index, description) => { 28 | const todos = getTodo(); 29 | const todo = todos.find((todoTask) => todoTask.index === index); 30 | todo.description = description; 31 | localStorage.setItem('todos', JSON.stringify(todos)); 32 | }; 33 | 34 | export { 35 | getTodo, addTodo, removeTodo, updateTodo, 36 | }; -------------------------------------------------------------------------------- /src/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 0; 3 | margin: 0; 4 | box-sizing: border-box; 5 | } 6 | 7 | .main { 8 | width: 40%; 9 | margin: 100px auto; 10 | box-shadow: rgba(0, 0, 0, 0.24) 0 3px 8px; 11 | } 12 | 13 | #title { 14 | font-size: 20px; 15 | margin: 0; 16 | color: #9a9ca2; 17 | } 18 | 19 | input { 20 | width: 100%; 21 | border: none; 22 | height: 50px; 23 | font-style: italic; 24 | } 25 | 26 | input:focus { 27 | outline: none; 28 | } 29 | 30 | input[type='checkbox'] { 31 | margin-right: 10px; 32 | } 33 | 34 | input[type='checkbox']:checked + input { 35 | text-decoration: line-through; 36 | color: #cacacb; 37 | } 38 | 39 | .header { 40 | display: flex; 41 | justify-content: space-between; 42 | align-items: center; 43 | padding: 10px; 44 | } 45 | 46 | .todo_form { 47 | border-bottom: 1px solid #f4f5f4; 48 | padding: 15px; 49 | } 50 | 51 | .todo_wrapper { 52 | display: flex; 53 | align-items: center; 54 | } 55 | 56 | .btn { 57 | border: none; 58 | background: none; 59 | outline: none; 60 | width: 25px; 61 | } 62 | 63 | .clear { 64 | text-align: center; 65 | background-color: #f6f6f6; 66 | cursor: pointer; 67 | } 68 | 69 | .clearText { 70 | margin: 0; 71 | padding: 15px; 72 | color: #cacacb; 73 | } 74 | 75 | .desciption { 76 | width: 100%; 77 | } 78 | 79 | #lists { 80 | padding: 0; 81 | margin: 0; 82 | list-style: none; 83 | } 84 | 85 | .listTask { 86 | display: flex; 87 | align-items: center; 88 | justify-content: space-between; 89 | border-bottom: 1px solid #f4f5f4; 90 | padding: 10px; 91 | } 92 | 93 | .listTaskWrapper { 94 | display: flex; 95 | align-items: center; 96 | gap: 10px; 97 | } 98 | 99 | #checkbox { 100 | width: 15px; 101 | border-color: #c0c0c3; 102 | } 103 | 104 | .todoBtn { 105 | border: none; 106 | background-color: white; 107 | outline: none; 108 | cursor: pointer; 109 | } 110 | -------------------------------------------------------------------------------- /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 | mode: 'development', 7 | entry: './src/index.js', 8 | devServer: { 9 | static: './dist', 10 | }, 11 | plugins: [ 12 | new HtmlWebpackPlugin({ 13 | template: './src/index.html', 14 | }), 15 | ], 16 | output: { 17 | filename: '[name].js', 18 | path: path.resolve(__dirname, 'dist'), 19 | clean: true, 20 | }, 21 | optimization: { 22 | runtimeChunk: 'single', 23 | }, 24 | module: { 25 | rules: [ 26 | { 27 | test: /\.css$/i, 28 | use: [ 29 | 'style-loader', 30 | 'css-loader', 31 | ], 32 | }, 33 | { 34 | test: /\.svg$/, 35 | loader: 'svg-inline-loader', 36 | }, 37 | ], 38 | }, 39 | }; --------------------------------------------------------------------------------