├── .DS_Store
├── README.md
└── examples
├── .DS_Store
├── AudioPlayer
├── High Energy beats.mp3
├── High Energy beats.wav
├── index.html
├── package-lock.json
├── package.json
├── src
│ ├── main.js
│ └── style.css
└── vite.config.js
├── Canvas1
├── README.md
├── index.html
├── package.json
├── plugins
│ └── vite-plugin-timemark.js
├── src
│ ├── filtering.js
│ ├── fonts
│ │ ├── OFL.txt
│ │ └── Tapestry-Regular.ttf
│ ├── images
│ │ └── background.jpg
│ ├── main.js
│ └── styles
│ │ ├── common.scss
│ │ ├── fonts.scss
│ │ └── main.scss
└── vite.config.js
├── ChromeExtension
├── 1
│ ├── README.md
│ ├── html
│ │ ├── hello.html
│ │ ├── popup.html
│ │ └── settings.html
│ ├── icons
│ │ ├── alert.png
│ │ ├── icon-128.png
│ │ ├── icon-16.png
│ │ ├── icon-32.png
│ │ └── icon-48.png
│ ├── js
│ │ ├── background.js
│ │ ├── content.js
│ │ ├── hello.js
│ │ └── popup.js
│ └── manifest.json
└── 2
│ ├── README.md
│ ├── css
│ └── toastify.css
│ ├── html
│ └── settings.html
│ ├── icons
│ ├── alert.png
│ ├── icon-128.png
│ ├── icon-16.png
│ ├── icon-32.png
│ └── icon-48.png
│ ├── js
│ ├── background.js
│ ├── content.js
│ └── toastify.js
│ └── manifest.json
├── IntersectionObserver
├── .gitignore
├── README.md
├── css
│ └── style.css
├── index.html
├── package-lock.json
├── package.json
├── public
│ └── spinner.svg
├── src
│ ├── api.js
│ ├── components
│ │ ├── comment.js
│ │ ├── post.js
│ │ └── user.js
│ ├── examples
│ │ ├── example1.js
│ │ ├── example2.js
│ │ ├── example3.js
│ │ ├── example4.js
│ │ ├── example5.js
│ │ ├── index.js
│ │ ├── start.js
│ │ └── start2.js
│ ├── main.js
│ └── tools.js
└── vite.config.js
├── MutationObserver
├── .gitignore
├── README.md
├── css
│ └── style.css
├── index.html
├── package-lock.json
├── package.json
├── public
│ └── spinner.svg
├── src
│ ├── examples
│ │ ├── example1.js
│ │ ├── example2.js
│ │ ├── example3.js
│ │ └── index.js
│ ├── main.js
│ └── tools.js
└── vite.config.js
├── ProxyAndReflect
├── .gitignore
├── README.md
├── index.html
├── javascript.svg
├── main.js
├── package-lock.json
├── package.json
├── public
│ └── vite.svg
├── src
│ ├── code1.js
│ ├── code2.js
│ └── code3.js
├── style.css
└── vite.config.js
├── ServiceWorker
├── README.md
├── assets
│ ├── image-1.png
│ ├── image-2.png
│ ├── image-3.png
│ ├── image-4.png
│ └── image-5.png
├── css
│ └── style.css
├── index.html
├── index.js
├── package.json
├── page1.html
├── page2.html
├── page3.html
├── public
│ └── sw.js
└── vite.config.js
├── SortChallenge
├── README.md
├── index.html
├── package.json
├── plugins
│ └── vite-plugin-timemark.js
├── src
│ ├── algorithms
│ │ ├── binaryTreeSort.js
│ │ ├── bubbleSort.js
│ │ ├── coctailSort.js
│ │ ├── combSort.js
│ │ ├── gnomeSort.js
│ │ ├── heapSort.js
│ │ ├── insertionSort.js
│ │ ├── introSort.js
│ │ ├── mergeSort.js
│ │ ├── quickJsSort.js
│ │ ├── quickSort.js
│ │ ├── selectionSort.js
│ │ ├── shellSort.js
│ │ ├── smoothSort.js
│ │ ├── stoogeSort.js
│ │ └── timSort.js
│ ├── chartEngine.js
│ ├── fonts
│ │ ├── OFL.txt
│ │ └── Tapestry-Regular.ttf
│ ├── images
│ │ └── background.jpg
│ ├── main.js
│ └── styles
│ │ ├── common.scss
│ │ ├── fonts.scss
│ │ └── main.scss
└── vite.config.js
├── Symbols
├── README.md
├── index.html
├── package.json
├── src
│ ├── examples
│ │ ├── example1.js
│ │ ├── example10.js
│ │ ├── example11.js
│ │ ├── example12.js
│ │ ├── example2.js
│ │ ├── example3.js
│ │ ├── example4.js
│ │ ├── example5.js
│ │ ├── example6.js
│ │ ├── example7.js
│ │ ├── example8.js
│ │ ├── example9.js
│ │ └── index.js
│ └── index.js
└── vite.config.js
├── TagLiteral
├── README.md
└── index.html
├── WasmRust
├── README.md
├── index.html
├── package-lock.json
├── package.json
├── src
│ ├── index.js
│ └── tools.js
├── vite.config.js
├── wasm-src
│ └── lib.rs
└── wasm_image_editor
│ ├── Cargo.lock
│ ├── Cargo.toml
│ └── src
│ └── lib.rs
├── WebRTS
├── .vscode
│ └── launch.json
├── README.md
├── index.html
├── package-lock.json
├── package.json
├── simple.html
├── src
│ ├── client
│ │ └── stream.js
│ ├── server
│ │ ├── server.js
│ │ └── streams.js
│ ├── streamer.js
│ ├── utils.js
│ └── viewer.js
├── streamer.html
├── viewer.html
└── vite.config.js
├── WebSocket
├── .vscode
│ └── launch.json
├── README.md
├── index.html
├── package-lock.json
├── package.json
├── src
│ ├── client
│ │ ├── main.js
│ │ ├── messages.js
│ │ ├── style.css
│ │ ├── usersList.js
│ │ └── websocket.js
│ ├── common
│ │ ├── constants.js
│ │ └── utils.js
│ └── server
│ │ ├── server.js
│ │ ├── streams.js
│ │ └── utils.js
└── vite.config.js
├── WebWorker
├── example1.js
├── example2.js
├── index.html
├── index.js
├── index2.html
├── index2.js
├── package-lock.json
├── package.json
├── vite.config.js
└── webworker.js
├── WebWorker2
├── index.html
├── package.json
├── scheme.pdf
├── src
│ ├── appConstants.js
│ └── index.js
└── vite.config.js
├── arrow-functions
├── .gitignore
├── README.md
├── index.html
├── package-lock.json
├── package.json
├── src
│ ├── example1.js
│ ├── example2.js
│ ├── example3.js
│ ├── example4.js
│ ├── example5.js
│ ├── favicon.ico
│ ├── index.js
│ └── tools.js
└── vite.config.js
├── drag-n-drop
├── .gitignore
├── README.md
├── package.json
├── public
│ └── index.html
├── src
│ ├── components
│ │ ├── cell.js
│ │ ├── data.json
│ │ ├── row.js
│ │ └── table.js
│ └── main.js
└── webpack.config.js
├── generator
├── index.html
├── index1.html
├── index2.html
├── index3.html
├── index4.html
├── index5.html
└── src
│ ├── generator1.js
│ ├── generator3.js
│ ├── generator4.js
│ ├── generator5.js
│ ├── index1.js
│ ├── index2.js
│ ├── index3.js
│ ├── index4.js
│ └── index5.js
├── macro-micro
├── example1.js
├── example2.js
├── example3.js
├── index.html
├── index.js
├── package-lock.json
├── package.json
└── vite.config.js
├── pagination
├── README.md
├── index.html
├── package.json
├── plugins
│ └── vite-plugin-timemark.js
├── server.mjs
├── src
│ ├── fonts
│ │ ├── OFL.txt
│ │ └── Tapestry-Regular.ttf
│ ├── images
│ │ └── background.jpg
│ ├── js
│ │ ├── api.js
│ │ ├── constants.js
│ │ ├── example1.js
│ │ ├── example2.js
│ │ ├── example3.js
│ │ ├── example4.js
│ │ ├── main.js
│ │ ├── main2.js
│ │ └── todo.js
│ └── styles
│ │ ├── common.scss
│ │ ├── fonts.scss
│ │ └── main.scss
└── vite.config.js
├── redux1
├── .gitignore
├── README.md
├── package.json
├── public
│ └── index.html
├── src
│ ├── components
│ │ ├── cell.js
│ │ ├── row.js
│ │ └── table.js
│ ├── data
│ │ └── data.json
│ ├── main.js
│ └── redux
│ │ ├── actions.js
│ │ ├── reducer.js
│ │ └── store.js
└── webpack.config.js
├── snowfall_css
├── README.md
├── img
│ ├── background1.png
│ ├── background2.png
│ └── background3.png
└── index.html
└── spa
├── bonus1
├── REST_server
│ ├── README.md
│ ├── db.json
│ ├── mongo-config.conf
│ ├── mongodb
│ │ └── fake.txt
│ ├── package-lock.json
│ ├── package.json
│ ├── scripts
│ │ └── generateDB.js
│ ├── server-config.json
│ ├── server.js
│ └── src
│ │ ├── common
│ │ ├── constants.js
│ │ └── utils.js
│ │ ├── decorators.js
│ │ ├── handlers
│ │ ├── auth
│ │ │ ├── auth.js
│ │ │ └── index.js
│ │ ├── comments
│ │ │ ├── comments.js
│ │ │ └── index.js
│ │ ├── posts
│ │ │ ├── index.js
│ │ │ └── posts.js
│ │ └── users
│ │ │ ├── index.js
│ │ │ └── users.js
│ │ ├── plugins
│ │ ├── awt-plugin.js
│ │ └── swagger-plugin.js
│ │ └── routes
│ │ ├── auth-routes.js
│ │ ├── comments-routes.js
│ │ ├── index.js
│ │ ├── posts-routes.js
│ │ ├── schemas
│ │ ├── allSchemas.js
│ │ ├── comment.js
│ │ ├── pagination.js
│ │ ├── post.js
│ │ ├── querystrings.js
│ │ └── user.js
│ │ └── users-routes.js
└── generateDB
│ ├── README.md
│ ├── db.json
│ ├── index.js
│ └── package.json
├── bonus2
├── README.md
├── index.html
├── package.json
├── plugins
│ └── vite-template-plugin.js
├── src
│ ├── api
│ │ ├── authApi.js
│ │ ├── baseApi.js
│ │ ├── commentsApi.js
│ │ ├── index.js
│ │ ├── postsApi.js
│ │ └── usersApi.js
│ ├── common
│ │ ├── constants.js
│ │ └── utils.js
│ ├── components
│ │ ├── app-component.js
│ │ ├── comment-component.js
│ │ ├── date-formatted.js
│ │ ├── fake-form.js
│ │ ├── index.js
│ │ ├── link-component.js
│ │ ├── list-component.js
│ │ ├── modal-dialog.js
│ │ ├── nav-component.js
│ │ ├── pagination-component.js
│ │ ├── post-component.js
│ │ ├── post-detail.js
│ │ ├── user-avatar.js
│ │ └── user-component.js
│ ├── index.js
│ ├── pages
│ │ ├── main.template
│ │ ├── main
│ │ │ ├── bottom.template
│ │ │ ├── left.template
│ │ │ ├── right.template
│ │ │ └── top.template
│ │ ├── post.template
│ │ ├── posts.template
│ │ ├── user.template
│ │ ├── userComments.template
│ │ ├── userPosts.template
│ │ └── users.template
│ ├── router
│ │ └── index.js
│ ├── service
│ │ ├── comments.js
│ │ ├── posts.js
│ │ └── users.js
│ └── styles
│ │ ├── common.scss
│ │ └── main.scss
└── vite.config.js
├── part1
├── README.md
├── index.html
├── package.json
├── plugins
│ └── vite-template-plugin.js
├── src
│ ├── common
│ │ ├── constants.js
│ │ └── utils.js
│ ├── index.js
│ ├── pages
│ │ ├── main.template
│ │ ├── posts.template
│ │ └── users.template
│ ├── router
│ │ └── index.js
│ └── styles
│ │ ├── common.scss
│ │ └── main.scss
└── vite.config.js
├── part2
├── README.md
├── index.html
├── package.json
├── plugins
│ └── vite-template-plugin.js
├── src
│ ├── common
│ │ ├── constants.js
│ │ └── utils.js
│ ├── components
│ │ ├── index.js
│ │ ├── link-component.js
│ │ └── nav-component.js
│ ├── index.js
│ ├── pages
│ │ ├── main.template
│ │ ├── posts.template
│ │ └── users.template
│ ├── router
│ │ └── index.js
│ └── styles
│ │ ├── common.scss
│ │ └── main.scss
└── vite.config.js
├── part3
├── README.md
├── db.json
├── index.html
├── package-lock.json
├── package.json
├── plugins
│ └── vite-template-plugin.js
├── src
│ ├── api
│ │ ├── baseApi.js
│ │ ├── commentsApi.js
│ │ ├── index.js
│ │ ├── postsApi.js
│ │ └── usersApi.js
│ ├── common
│ │ ├── constants.js
│ │ └── utils.js
│ ├── components
│ │ ├── index.js
│ │ ├── link-component.js
│ │ └── nav-component.js
│ ├── index.js
│ ├── pages
│ │ ├── main.template
│ │ ├── posts.template
│ │ └── users.template
│ ├── router
│ │ └── index.js
│ └── styles
│ │ ├── common.scss
│ │ └── main.scss
└── vite.config.js
├── part4
├── README.md
├── db.json
├── index.html
├── package-lock.json
├── package.json
├── plugins
│ └── vite-template-plugin.js
├── src
│ ├── api
│ │ ├── baseApi.js
│ │ ├── commentsApi.js
│ │ ├── index.js
│ │ ├── postsApi.js
│ │ └── usersApi.js
│ ├── common
│ │ ├── constants.js
│ │ └── utils.js
│ ├── components
│ │ ├── index.js
│ │ ├── link-component.js
│ │ ├── nav-component.js
│ │ ├── pagination-component.js
│ │ ├── post-component.js
│ │ ├── posts-component.js
│ │ └── user-avatar.js
│ ├── index.js
│ ├── pages
│ │ ├── main.template
│ │ ├── posts.template
│ │ └── users.template
│ ├── router
│ │ └── index.js
│ ├── service
│ │ └── posts.js
│ └── styles
│ │ ├── common.scss
│ │ └── main.scss
└── vite.config.js
├── part5
├── README.md
├── db.json
├── index.html
├── package-lock.json
├── package.json
├── plugins
│ └── vite-template-plugin.js
├── src
│ ├── api
│ │ ├── baseApi.js
│ │ ├── commentsApi.js
│ │ ├── index.js
│ │ ├── postsApi.js
│ │ └── usersApi.js
│ ├── common
│ │ ├── constants.js
│ │ └── utils.js
│ ├── components
│ │ ├── index.js
│ │ ├── link-component.js
│ │ ├── nav-component.js
│ │ ├── pagination-component.js
│ │ ├── post-component.js
│ │ ├── posts-component.js
│ │ └── user-avatar.js
│ ├── index.js
│ ├── pages
│ │ ├── main.template
│ │ ├── posts.template
│ │ └── users.template
│ ├── router
│ │ └── index.js
│ ├── service
│ │ └── posts.js
│ └── styles
│ │ ├── common.scss
│ │ └── main.scss
└── vite.config.js
├── part6
├── README.md
├── db.json
├── index.html
├── package-lock.json
├── package.json
├── plugins
│ └── vite-template-plugin.js
├── src
│ ├── api
│ │ ├── baseApi.js
│ │ ├── commentsApi.js
│ │ ├── index.js
│ │ ├── postsApi.js
│ │ └── usersApi.js
│ ├── common
│ │ ├── constants.js
│ │ └── utils.js
│ ├── components
│ │ ├── index.js
│ │ ├── link-component.js
│ │ ├── list-component.js
│ │ ├── nav-component.js
│ │ ├── pagination-component.js
│ │ ├── post-component.js
│ │ ├── posts-component.js
│ │ ├── user-avatar.js
│ │ └── user-component.js
│ ├── index.js
│ ├── pages
│ │ ├── main.template
│ │ ├── posts.template
│ │ └── users.template
│ ├── router
│ │ └── index.js
│ ├── service
│ │ ├── posts.js
│ │ └── users.js
│ └── styles
│ │ ├── common.scss
│ │ └── main.scss
└── vite.config.js
├── part7
├── README.md
├── db.json
├── index.html
├── package.json
├── plugins
│ └── vite-template-plugin.js
├── src
│ ├── api
│ │ ├── baseApi.js
│ │ ├── commentsApi.js
│ │ ├── index.js
│ │ ├── postsApi.js
│ │ └── usersApi.js
│ ├── common
│ │ ├── constants.js
│ │ └── utils.js
│ ├── components
│ │ ├── comment-component.js
│ │ ├── date-formatted.js
│ │ ├── index.js
│ │ ├── link-component.js
│ │ ├── list-component.js
│ │ ├── nav-component.js
│ │ ├── pagination-component.js
│ │ ├── post-component.js
│ │ ├── post-detail.js
│ │ ├── user-avatar.js
│ │ └── user-component.js
│ ├── index.js
│ ├── pages
│ │ ├── main.template
│ │ ├── post.template
│ │ ├── posts.template
│ │ ├── user.template
│ │ ├── userComments.template
│ │ ├── userPosts.template
│ │ └── users.template
│ ├── router
│ │ └── index.js
│ ├── service
│ │ ├── comments.js
│ │ ├── posts.js
│ │ └── users.js
│ └── styles
│ │ ├── common.scss
│ │ └── main.scss
└── vite.config.js
└── part8
├── README.md
├── db.json
├── index.html
├── package.json
├── plugins
└── vite-template-plugin.js
├── src
├── api
│ ├── baseApi.js
│ ├── commentsApi.js
│ ├── index.js
│ ├── postsApi.js
│ └── usersApi.js
├── common
│ ├── constants.js
│ └── utils.js
├── components
│ ├── app-component.js
│ ├── comment-component.js
│ ├── date-formatted.js
│ ├── fake-form.js
│ ├── index.js
│ ├── link-component.js
│ ├── list-component.js
│ ├── modal-dialog.js
│ ├── nav-component.js
│ ├── pagination-component.js
│ ├── post-component.js
│ ├── post-detail.js
│ ├── user-avatar.js
│ └── user-component.js
├── index.js
├── pages
│ ├── main.template
│ ├── main
│ │ ├── bottom.template
│ │ ├── left.template
│ │ ├── right.template
│ │ └── top.template
│ ├── post.template
│ ├── posts.template
│ ├── user.template
│ ├── userComments.template
│ ├── userPosts.template
│ └── users.template
├── router
│ └── index.js
├── service
│ ├── comments.js
│ ├── posts.js
│ └── users.js
└── styles
│ ├── common.scss
│ └── main.scss
└── vite.config.js
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/.DS_Store
--------------------------------------------------------------------------------
/examples/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/.DS_Store
--------------------------------------------------------------------------------
/examples/AudioPlayer/High Energy beats.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/AudioPlayer/High Energy beats.mp3
--------------------------------------------------------------------------------
/examples/AudioPlayer/High Energy beats.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/AudioPlayer/High Energy beats.wav
--------------------------------------------------------------------------------
/examples/AudioPlayer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "audioanalize",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "preview": "vite preview"
10 | },
11 | "devDependencies": {
12 | "vite": "^6.2.0"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/examples/AudioPlayer/src/style.css:
--------------------------------------------------------------------------------
1 | .row {
2 | display: flex;
3 | gap: 10px;
4 | align-items: center;
5 | margin: 10px 0;
6 | }
7 |
8 | .input-holder {
9 | display: flex;
10 | gap: 10px;
11 | align-items: center;
12 | }
13 |
14 | .audio-holder {
15 | display: grid;
16 | grid-template-columns: auto 100px 300px;
17 | }
18 |
19 | #audio{
20 | width: 100%;
21 | }
--------------------------------------------------------------------------------
/examples/AudioPlayer/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 |
3 | export default defineConfig({
4 | server: {
5 | host: '0.0.0.0',
6 | port: 3000,
7 | }
8 | })
--------------------------------------------------------------------------------
/examples/Canvas1/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Image editor
7 |
8 |
9 |
10 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/examples/Canvas1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "easy-it-vitejs-setup",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "vite",
8 | "build": "vite build",
9 | "serve": "vite preview --port 3000",
10 | "test": "echo \"Error: no test specified\" && exit 1"
11 | },
12 | "keywords": [],
13 | "browserslist": [
14 | "cover 99.5%"
15 | ],
16 | "author": "",
17 | "license": "ISC",
18 | "devDependencies": {
19 | "@vitejs/plugin-legacy": "^5.2.0",
20 | "sass": "^1.69.6",
21 | "vite": "^5.0.10"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/examples/Canvas1/src/fonts/Tapestry-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/Canvas1/src/fonts/Tapestry-Regular.ttf
--------------------------------------------------------------------------------
/examples/Canvas1/src/images/background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/Canvas1/src/images/background.jpg
--------------------------------------------------------------------------------
/examples/Canvas1/src/styles/common.scss:
--------------------------------------------------------------------------------
1 | @import 'fonts.scss';
2 |
3 | body {
4 | margin: 0;
5 | padding: 0;
6 | background-image: url(../images/background.jpg);
7 | }
8 |
9 | .page-header{
10 | text-align: center;
11 | font-family: 'Square Peg', cursive;
12 | font-size: 50px;
13 | }
14 |
15 | .image-block{
16 | display: flex;
17 | align-items: center;
18 | justify-content: center;
19 | }
--------------------------------------------------------------------------------
/examples/Canvas1/src/styles/fonts.scss:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'Tapestry';
3 | src: local('Tapestry'), url(../fonts/Tapestry-Regular.ttf) format('truetype');
4 | }
5 |
6 | @import url('https://fonts.googleapis.com/css2?family=Square+Peg&display=swap');
--------------------------------------------------------------------------------
/examples/Canvas1/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import legacy from "@vitejs/plugin-legacy";
3 | import timeMarkPlugin from "./plugins/vite-plugin-timemark";
4 |
5 | export default defineConfig({
6 | build: {
7 | target: "es2017",
8 | outDir: "build",
9 | rollupOptions: {
10 | output: {
11 | assetFileNames: ({ name }) => {
12 | if (/\.(gif|jpe?g|png|svg)$/.test(name ?? "")) {
13 | return "assets/images/[name]-[hash][extname]";
14 | }
15 |
16 | if (/\.(ttf|otf|fnt|woff)$/.test(name ?? "")) {
17 | return "assets/fonts/[name]-[hash][extname]";
18 | }
19 |
20 | if (/\.css$/.test(name ?? "")) {
21 | return "assets/css/[name]-[hash][extname]";
22 | }
23 |
24 | return "assets/[name]-[hash][extname]";
25 | },
26 | },
27 | },
28 | },
29 | server: {
30 | port: 3000,
31 | host: "0.0.0.0",
32 | hmr: true,
33 | },
34 | plugins: [
35 | legacy({
36 | targets: ["defaults", "not IE 11"],
37 | }),
38 | timeMarkPlugin(),
39 | ],
40 | });
41 |
--------------------------------------------------------------------------------
/examples/ChromeExtension/1/html/settings.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | EasyIt Extension - settings
4 |
5 | A lot of settings could be here ;)
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/ChromeExtension/1/icons/alert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/ChromeExtension/1/icons/alert.png
--------------------------------------------------------------------------------
/examples/ChromeExtension/1/icons/icon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/ChromeExtension/1/icons/icon-128.png
--------------------------------------------------------------------------------
/examples/ChromeExtension/1/icons/icon-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/ChromeExtension/1/icons/icon-16.png
--------------------------------------------------------------------------------
/examples/ChromeExtension/1/icons/icon-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/ChromeExtension/1/icons/icon-32.png
--------------------------------------------------------------------------------
/examples/ChromeExtension/1/icons/icon-48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/ChromeExtension/1/icons/icon-48.png
--------------------------------------------------------------------------------
/examples/ChromeExtension/1/js/hello.js:
--------------------------------------------------------------------------------
1 | const onClick = async(e) => {
2 | let queryOptions = { active: true, lastFocusedWindow: true };
3 | const [tab] = await chrome.tabs.query(queryOptions)
4 | chrome.tabs.remove(tab.id)
5 | }
6 |
7 | const btn = document.querySelector('.ok-button')
8 | if(btn){
9 | btn.addEventListener('click', onClick)
10 | }
11 |
--------------------------------------------------------------------------------
/examples/ChromeExtension/2/html/settings.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | EasyIt Extension - settings
4 |
5 | A lot of settings could be here ;)
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/ChromeExtension/2/icons/alert.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/ChromeExtension/2/icons/alert.png
--------------------------------------------------------------------------------
/examples/ChromeExtension/2/icons/icon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/ChromeExtension/2/icons/icon-128.png
--------------------------------------------------------------------------------
/examples/ChromeExtension/2/icons/icon-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/ChromeExtension/2/icons/icon-16.png
--------------------------------------------------------------------------------
/examples/ChromeExtension/2/icons/icon-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/ChromeExtension/2/icons/icon-32.png
--------------------------------------------------------------------------------
/examples/ChromeExtension/2/icons/icon-48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/ChromeExtension/2/icons/icon-48.png
--------------------------------------------------------------------------------
/examples/ChromeExtension/2/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "manifest_version": 3,
3 | "name": "EasyIt Extension",
4 | "description": "EasyIt Extension - clipboard",
5 | "version": "1.0",
6 | "author": "EasyIT development",
7 | "action": {
8 | "default_title": "Enable Clipboard handling",
9 | "default_icon": "icons/icon-32.png"
10 | },
11 | "icons": {
12 | "16": "icons/icon-16.png",
13 | "32": "icons/icon-32.png",
14 | "48": "icons/icon-48.png",
15 | "128": "icons/icon-128.png"
16 | },
17 | "content_scripts": [
18 | {
19 | "js": [
20 | "js/content.js",
21 | "js/toastify.js"
22 | ],
23 | "css": [
24 | "css/toastify.css"
25 | ],
26 | "matches": [
27 | ""
28 | ]
29 | }
30 | ],
31 | "permissions": [
32 | "tabs",
33 | "activeTab",
34 | "storage",
35 | "contextMenus"
36 | ],
37 | "host_permissions": [
38 | ""
39 | ],
40 | "background": {
41 | "service_worker": "js/background.js"
42 | }
43 | }
--------------------------------------------------------------------------------
/examples/IntersectionObserver/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/examples/IntersectionObserver/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Intersection Observer examples
8 |
9 |
10 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/examples/IntersectionObserver/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "intersectionobserver",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "preview": "vite preview"
10 | },
11 | "devDependencies": {
12 | "vite": "^5.4.1"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/examples/IntersectionObserver/src/components/comment.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/IntersectionObserver/src/components/comment.js
--------------------------------------------------------------------------------
/examples/IntersectionObserver/src/components/post.js:
--------------------------------------------------------------------------------
1 | export const createPost = (postData) => {
2 |
3 | const post = document.createElement('div')
4 | post.dataset.postId = postData.id;
5 | post.dataset.userId = postData.userId;
6 | post.className = 'post'
7 | post.innerHTML = `
8 | ${postData.title}
9 | ${postData.body}
10 | `
11 | return post
12 | }
--------------------------------------------------------------------------------
/examples/IntersectionObserver/src/examples/index.js:
--------------------------------------------------------------------------------
1 | export { default as start } from "./start";
2 | export { default as start2 } from "./start2";
3 | export { default as example1 } from "./example1";
4 | export { default as example2 } from "./example2";
5 | export { default as example3 } from "./example3";
6 | export { default as example4 } from "./example4";
7 | export { default as example5 } from "./example5";
8 |
--------------------------------------------------------------------------------
/examples/IntersectionObserver/src/tools.js:
--------------------------------------------------------------------------------
1 | export const getUserAvatarUrl = (userName) => {
2 | return `https://api.dicebear.com/9.x/personas/svg?seed=${userName}`;
3 | };
4 |
--------------------------------------------------------------------------------
/examples/IntersectionObserver/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 |
3 | export default defineConfig({
4 | server: {
5 | port: 3000,
6 | host: '0.0.0.0'
7 | }
8 | })
--------------------------------------------------------------------------------
/examples/MutationObserver/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/examples/MutationObserver/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "intersectionobserver",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "preview": "vite preview"
10 | },
11 | "devDependencies": {
12 | "vite": "^5.4.1"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/examples/MutationObserver/src/examples/example1.js:
--------------------------------------------------------------------------------
1 | import { changeCanvas } from "../tools";
2 |
3 | let div = null;
4 | let canvas = null;
5 | let context = null;
6 | let interval = null;
7 |
8 |
9 | const cleanUp = () => {
10 | if (interval) {
11 | clearInterval(interval);
12 | interval = null;
13 | }
14 | };
15 |
16 | const run = () => {
17 | div = document.querySelector("#container");
18 | canvas = document.querySelector("#canvas");
19 | context = canvas.getContext("2d");
20 | if (context) {
21 | // Проверяем размеры div каждую секунду
22 | interval = setInterval(()=>{changeCanvas({div, canvas, context})}, 1000);
23 | changeCanvas({div, canvas, context});
24 | }
25 | return div;
26 | };
27 |
28 | export default {
29 | run,
30 | cleanUp,
31 | };
32 |
--------------------------------------------------------------------------------
/examples/MutationObserver/src/examples/example2.js:
--------------------------------------------------------------------------------
1 | import { changeCanvas } from "../tools";
2 |
3 | let div = null;
4 | let canvas = null;
5 | let context = null;
6 | let observer = null;
7 |
8 | const cleanUp = () => {
9 | if (observer) {
10 | observer.disconnect();
11 | observer = null;
12 | }
13 | };
14 |
15 | const run = () => {
16 | div = document.querySelector("#container");
17 | canvas = document.querySelector("#canvas");
18 | context = canvas.getContext("2d");
19 | if (context && div) {
20 | // Создаем observer для отслеживания изменений стилей и атрибутов
21 | observer = new MutationObserver((mutations) => {
22 | mutations.forEach((mutation) => {
23 | if (mutation.type === "attributes") {
24 | changeCanvas({div, canvas, context});
25 | }
26 | });
27 | });
28 | observer.observe(div, { attributes: true });
29 | // Первоначальная настройка
30 | changeCanvas({div, canvas, context});
31 | }
32 | return div;
33 | };
34 |
35 | export default {
36 | run,
37 | cleanUp,
38 | };
39 |
40 |
--------------------------------------------------------------------------------
/examples/MutationObserver/src/examples/index.js:
--------------------------------------------------------------------------------
1 | export { default as example1 } from "./example1";
2 | export { default as example2 } from "./example2";
3 | export { default as example3 } from "./example3";
4 |
--------------------------------------------------------------------------------
/examples/MutationObserver/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 |
3 | export default defineConfig({
4 | server: {
5 | port: 3000,
6 | host: '0.0.0.0'
7 | }
8 | })
--------------------------------------------------------------------------------
/examples/ProxyAndReflect/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/examples/ProxyAndReflect/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite App
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/ProxyAndReflect/javascript.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/examples/ProxyAndReflect/main.js:
--------------------------------------------------------------------------------
1 | import code1 from './src/code1'
2 | import code2 from './src/code2'
3 | import code3 from './src/code3'
4 |
5 |
6 | // code1();
7 | //code2();
8 | code3();
9 |
--------------------------------------------------------------------------------
/examples/ProxyAndReflect/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "proxyandreflect",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "preview": "vite preview"
10 | },
11 | "devDependencies": {
12 | "vite": "^5.4.8"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/examples/ProxyAndReflect/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 |
3 | export default defineConfig({
4 | server: {
5 | host: '0.0.0.0',
6 | port: 3000,
7 | }
8 | })
--------------------------------------------------------------------------------
/examples/ServiceWorker/README.md:
--------------------------------------------------------------------------------
1 | # Web service example
2 |
3 | ## **Добавляем возможность офф-лайновой работы для любого сайта или веб приложения**
4 |
5 |
6 | ## Как пользоваться
7 |
8 | ```
9 | npm install
10 | npm run build
11 | ```
12 | или
13 |
14 | ```
15 | npm install
16 | npm run start
17 | ```
18 |
19 | или
20 |
21 | ```
22 | npm run build
23 | cd build
24 | npx http-server-spa ./ ./index.html 5001
25 | ```
26 | ## Видео с объяснением как это все работает здесь:
27 | https://youtu.be/bgp1NR0OXOA
28 |
29 | ## Еще по vitejs
30 |
31 | https://youtu.be/wIEauCguZGI
32 | https://youtu.be/t98Q9hliZZo
33 | https://youtu.be/aMzCDR_MHF0
34 | https://youtu.be/TZN6dC7ZOs0
35 |
36 |
37 | ## Полезные видео по настройке webpack:
38 |
39 |
40 | Минимальная конфигурация:
41 |
42 | https://youtu.be/unEl3Hezwpw
43 |
44 | Настройка горячей перезагрузки:
45 |
46 | https://youtu.be/oOpzkF2nU0s
47 |
48 | Настройка сборки проекта с подгрузкой файлов css/scss/изображений:
49 |
50 | https://youtu.be/3B-NGZmMe-Y
51 |
52 | Модульный принцип конфигурации проекта:
53 |
54 | https://youtu.be/fnUqyWyG5kk
55 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/examples/ServiceWorker/assets/image-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/ServiceWorker/assets/image-1.png
--------------------------------------------------------------------------------
/examples/ServiceWorker/assets/image-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/ServiceWorker/assets/image-2.png
--------------------------------------------------------------------------------
/examples/ServiceWorker/assets/image-3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/ServiceWorker/assets/image-3.png
--------------------------------------------------------------------------------
/examples/ServiceWorker/assets/image-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/ServiceWorker/assets/image-4.png
--------------------------------------------------------------------------------
/examples/ServiceWorker/assets/image-5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/ServiceWorker/assets/image-5.png
--------------------------------------------------------------------------------
/examples/ServiceWorker/css/style.css:
--------------------------------------------------------------------------------
1 | .links{
2 | display: flex;
3 | align-items: center;
4 | justify-content: space-around;
5 | }
6 |
7 | .links .link{
8 | background-color: #aaa;
9 | padding: 5px 20px;
10 | color: #fff;
11 | }
12 |
13 | .links .link.selected{
14 | background-color: #00a;
15 | }
16 |
17 | .links .link a{
18 | text-decoration: none;
19 | color: #fff;
20 | }
21 |
22 | .links .link:hover a{
23 | color: #eee;
24 | }
25 |
26 | .container {
27 | display: flex;
28 | flex-wrap: wrap;
29 | align-items: center;
30 | justify-content: center;
31 | }
32 |
33 | .container .card {
34 | display: flex;
35 | flex-direction: column;
36 | justify-content: center;
37 | align-items: center;
38 | padding: 10px;
39 | margin: 10px;
40 | border: 1px solid #ccc;
41 | border-radius: 8px;
42 | }
43 |
44 | .container .card .img{
45 |
46 | }
47 |
48 | .container .card .text{
49 | font-size: 20pt;
50 | color: rgba(0,0,0, 0.3);
51 | padding: 10px;
52 | }
53 |
54 | .container.page1{
55 | flex-direction: row-reverse;
56 | }
57 |
58 | .container.page2{
59 | flex-direction: column;
60 | }
61 |
62 | .container.page3{
63 | flex-direction: column-reverse;
64 | }
--------------------------------------------------------------------------------
/examples/ServiceWorker/index.js:
--------------------------------------------------------------------------------
1 | const onWorkerReady = () => {
2 | console.log('SW is ready');
3 | }
4 |
5 |
6 | navigator.serviceWorker.register('sw.js');
7 |
8 | navigator.serviceWorker.ready.then(onWorkerReady);
9 |
--------------------------------------------------------------------------------
/examples/ServiceWorker/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "serviceworker",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "vite",
8 | "build": "vite build",
9 | "test": "echo \"Error: no test specified\" && exit 1"
10 | },
11 | "keywords": [],
12 | "author": "",
13 | "license": "ISC",
14 | "devDependencies": {
15 | "vite": "^3.2.1"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/examples/ServiceWorker/vite.config.js:
--------------------------------------------------------------------------------
1 | import { resolve } from "path";
2 | import { defineConfig } from "vite";
3 |
4 | export default defineConfig({
5 | server: {
6 | host: "0.0.0.0",
7 | port: 5000,
8 | },
9 | build: {
10 | target: "es2017",
11 | outDir: "build",
12 | rollupOptions: {
13 | input: {
14 | main: resolve(__dirname, "./index.html"),
15 | page1: resolve(__dirname, "./page1.html"),
16 | page2: resolve(__dirname, "./page2.html"),
17 | page3: resolve(__dirname, "./page3.html"),
18 | },
19 | output: {
20 | assetFileNames: ({ name }) => {
21 | if (/\.(gif|jpe?g|png|svg)$/.test(name ?? "")) {
22 | return "assets/images/[name]-[hash][extname]";
23 | }
24 |
25 | if (/\.(ttf|otf|fnt|woff)$/.test(name ?? "")) {
26 | return "assets/fonts/[name]-[hash][extname]";
27 | }
28 |
29 | if (/\.css$/.test(name ?? "")) {
30 | return "assets/css/[name]-[hash][extname]";
31 | }
32 |
33 | return "assets/[name]-[hash][extname]";
34 | },
35 | },
36 | },
37 | },
38 | });
39 |
--------------------------------------------------------------------------------
/examples/SortChallenge/README.md:
--------------------------------------------------------------------------------
1 | # Проверяем скорость работы различных алгоритмов сортировки
2 |
3 |
4 | ## Как пользоваться
5 |
6 | ```
7 | npm install
8 | npm run start
9 |
10 | ```
11 |
12 | ## Работающий пример (с некоторыми изменениями):
13 | https://easy-linux.github.io/sort/
14 |
15 | ## Видео с объяснением как это все работает здесь:
16 | https://youtu.be/CmEoY7IcZbc
17 |
18 | ## Сайт где можно найти нужные шрифты:
19 |
20 | https://fonts.google.com/
21 |
22 | ## Еще по vitejs
23 |
24 | https://youtu.be/wIEauCguZGI
25 | https://youtu.be/t98Q9hliZZo
26 | https://youtu.be/aMzCDR_MHF0
27 | https://youtu.be/TZN6dC7ZOs0
28 |
29 |
30 | ## Полезные видео по настройке webpack:
31 |
32 |
33 | Минимальная конфигурация:
34 |
35 | https://youtu.be/unEl3Hezwpw
36 |
37 | Настройка горячей перезагрузки:
38 |
39 | https://youtu.be/oOpzkF2nU0s
40 |
41 | Настройка сборки проекта с подгрузкой файлов css/scss/изображений:
42 |
43 | https://youtu.be/3B-NGZmMe-Y
44 |
45 | Модульный принцип конфигурации проекта:
46 |
47 | https://youtu.be/fnUqyWyG5kk
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/examples/SortChallenge/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "easy-it-vitejs-setup",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "vite",
8 | "build": "vite build",
9 | "serve": "vite preview --port 3000",
10 | "test": "echo \"Error: no test specified\" && exit 1"
11 | },
12 | "keywords": [],
13 | "browserslist": [
14 | "cover 99.5%"
15 | ],
16 | "author": "",
17 | "license": "ISC",
18 | "devDependencies": {
19 | "@vitejs/plugin-legacy": "^4.0.1",
20 | "sass": "^1.58.3",
21 | "vite": "^4.1.4"
22 | },
23 | "dependencies": {
24 | "chart.js": "^4.2.1"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/examples/SortChallenge/src/algorithms/bubbleSort.js:
--------------------------------------------------------------------------------
1 | /*
2 | Пузырьковая сортировка
3 | */
4 |
5 | const bubbleSort = (arr) => {
6 | let len = arr.length;
7 | for (let i = 0; i < len; i++) {
8 | for (let j = 0; j < len - 1; j++) {
9 | if (arr[j] > arr[j + 1]) {
10 | let temp = arr[j];
11 | arr[j] = arr[j + 1];
12 | arr[j + 1] = temp;
13 | }
14 | }
15 | }
16 | return arr;
17 | }
18 |
19 | export default bubbleSort
--------------------------------------------------------------------------------
/examples/SortChallenge/src/algorithms/coctailSort.js:
--------------------------------------------------------------------------------
1 | /*
2 | Сортировка перемешиванием
3 | */
4 |
5 | const cocktailSort = (arr) => {
6 | let start = 0;
7 | let end = arr.length - 1;
8 | let swapped = true;
9 |
10 | while (swapped) {
11 | // Проход с начала к концу
12 | swapped = false;
13 | for (let i = start; i < end; i++) {
14 | if (arr[i] > arr[i + 1]) {
15 | let temp = arr[i];
16 | arr[i] = arr[i + 1];
17 | arr[i + 1] = temp;
18 | swapped = true;
19 | }
20 | }
21 | end--;
22 |
23 | // Проход с конца к началу
24 | for (let j = end; j > start; j--) {
25 | if (arr[j] < arr[j - 1]) {
26 | let temp = arr[j];
27 | arr[j] = arr[j - 1];
28 | arr[j - 1] = temp;
29 | swapped = true;
30 | }
31 | }
32 | start++;
33 | }
34 |
35 | return arr;
36 | }
37 |
38 | // Пример использования
39 | //let arr = [64, 34, 25, 12, 22, 11, 90];
40 | //var sortedArr = cocktailSort(arr);
41 | //console.log(sortedArr); // [11, 12, 22, 25, 34, 64, 90]
42 |
43 | export default cocktailSort
44 |
--------------------------------------------------------------------------------
/examples/SortChallenge/src/algorithms/combSort.js:
--------------------------------------------------------------------------------
1 | /*
2 | Сортировка расческой
3 | */
4 |
5 | const combSort = (arr) => {
6 | const shrinkFactor = 1.3;
7 | let gap = arr.length;
8 | let swapped = true;
9 | while (gap > 1 || swapped) {
10 | gap = Math.floor(gap / shrinkFactor);
11 | if (gap < 1) {
12 | gap = 1;
13 | }
14 | swapped = false;
15 | let i = 0;
16 | while (i + gap < arr.length) {
17 | if (arr[i] > arr[i + gap]) {
18 | [arr[i], arr[i + gap]] = [arr[i + gap], arr[i]];
19 | swapped = true;
20 | }
21 | i++;
22 | }
23 | }
24 | return arr;
25 | }
26 |
27 | export default combSort
--------------------------------------------------------------------------------
/examples/SortChallenge/src/algorithms/gnomeSort.js:
--------------------------------------------------------------------------------
1 | /*
2 | Гномья сортировка
3 | */
4 |
5 | const gnomeSort = (arr) => {
6 | let len = arr.length;
7 | let pos = 0;
8 |
9 | while (pos < len) {
10 | if (pos === 0 || arr[pos] >= arr[pos - 1]) {
11 | pos++;
12 | } else {
13 | let temp = arr[pos];
14 | arr[pos] = arr[pos - 1];
15 | arr[pos - 1] = temp;
16 | pos--;
17 | }
18 | }
19 |
20 | return arr;
21 | }
22 |
23 | export default gnomeSort
24 |
--------------------------------------------------------------------------------
/examples/SortChallenge/src/algorithms/heapSort.js:
--------------------------------------------------------------------------------
1 | /*
2 | Пирамидальная сортировка
3 | */
4 |
5 | const heapify = (arr, n, i) => {
6 | let largest = i;
7 | const left = 2 * i + 1;
8 | const right = 2 * i + 2;
9 | if (left < n && arr[left] > arr[largest]) {
10 | largest = left;
11 | }
12 | if (right < n && arr[right] > arr[largest]) {
13 | largest = right;
14 | }
15 | if (largest !== i) {
16 | [arr[i], arr[largest]] = [arr[largest], arr[i]];
17 | heapify(arr, n, largest);
18 | }
19 | }
20 |
21 | const heapSort = (arr) => {
22 | const n = arr.length;
23 | for (let i = Math.floor(n / 2) - 1; i >= 0; i--) {
24 | heapify(arr, n, i);
25 | }
26 | for (let i = n - 1; i > 0; i--) {
27 | [arr[0], arr[i]] = [arr[i], arr[0]];
28 | heapify(arr, i, 0);
29 | }
30 | return arr;
31 | }
32 |
33 | export default heapSort
--------------------------------------------------------------------------------
/examples/SortChallenge/src/algorithms/insertionSort.js:
--------------------------------------------------------------------------------
1 | /*
2 | Сортировка вставками
3 | */
4 |
5 | const insertionSort = (arr) => {
6 | let len = arr.length;
7 | for (let i = 1; i < len; i++) {
8 | let key = arr[i];
9 | let j = i - 1;
10 | while (j >= 0 && arr[j] > key) {
11 | arr[j + 1] = arr[j];
12 | j--;
13 | }
14 | arr[j + 1] = key;
15 | }
16 | return arr;
17 | }
18 |
19 | export default insertionSort
--------------------------------------------------------------------------------
/examples/SortChallenge/src/algorithms/mergeSort.js:
--------------------------------------------------------------------------------
1 | /*
2 | Сортировка слиянием
3 | */
4 |
5 | function merge(left, right) {
6 | let result = [];
7 | while (left.length && right.length) {
8 | if (left[0] <= right[0]) {
9 | result.push(left.shift());
10 | } else {
11 | result.push(right.shift());
12 | }
13 | }
14 | while (left.length) {
15 | result.push(left.shift());
16 | }
17 | while (right.length) {
18 | result.push(right.shift());
19 | }
20 | return result;
21 | }
22 |
23 | const mergeSort = (arr) => {
24 | if (arr.length < 2) {
25 | return arr;
26 | }
27 |
28 | let middle = Math.floor(arr.length / 2);
29 | let left = arr.slice(0, middle);
30 | let right = arr.slice(middle);
31 |
32 | return merge(mergeSort(left), mergeSort(right));
33 | }
34 |
35 | export default mergeSort
--------------------------------------------------------------------------------
/examples/SortChallenge/src/algorithms/quickJsSort.js:
--------------------------------------------------------------------------------
1 | /*
2 | Быстрая JS сортировка
3 | */
4 |
5 | const quickJsSort = (arr) => {
6 | return arr.sort((a, b) => {
7 | if (a > b) return 1;
8 | if (a < b) return -1;
9 | return 0;
10 | });
11 | };
12 |
13 | export default quickJsSort;
14 |
--------------------------------------------------------------------------------
/examples/SortChallenge/src/algorithms/quickSort.js:
--------------------------------------------------------------------------------
1 | /*
2 | Быстрая сортировка
3 | */
4 |
5 | const quickSort = (arr) => {
6 | if (arr.length <= 1) {
7 | return arr;
8 | }
9 | const pivot = arr[0];
10 | const left = [];
11 | const right = [];
12 | for (let i = 1; i < arr.length; i++) {
13 | if (arr[i] < pivot) {
14 | left.push(arr[i]);
15 | } else {
16 | right.push(arr[i]);
17 | }
18 | }
19 | return [...quickSort(left), pivot, ...quickSort(right)];
20 | }
21 |
22 | export default quickSort
23 |
24 |
--------------------------------------------------------------------------------
/examples/SortChallenge/src/algorithms/selectionSort.js:
--------------------------------------------------------------------------------
1 | /*
2 | Сортировка выбором
3 | */
4 |
5 | const selectionSort = (arr) => {
6 | for (let i = 0; i < arr.length; i++) {
7 | let minIndex = i;
8 | for (let j = i + 1; j < arr.length; j++) {
9 | if (arr[j] < arr[minIndex]) {
10 | minIndex = j;
11 | }
12 | }
13 | if (minIndex !== i) {
14 | [arr[i], arr[minIndex]] = [arr[minIndex], arr[i]];
15 | }
16 | }
17 | return arr;
18 | }
19 |
20 | export default selectionSort
--------------------------------------------------------------------------------
/examples/SortChallenge/src/algorithms/shellSort.js:
--------------------------------------------------------------------------------
1 | /**
2 | Сортирвока Шелла
3 | */
4 |
5 | const shellSort = (arr) => {
6 | let gap = Math.floor(arr.length / 2);
7 | while (gap > 0) {
8 | for (let i = gap; i < arr.length; i++) {
9 | let j = i;
10 | const temp = arr[i];
11 | while (j >= gap && arr[j - gap] > temp) {
12 | arr[j] = arr[j - gap];
13 | j -= gap;
14 | }
15 | arr[j] = temp;
16 | }
17 | gap = Math.floor(gap / 2);
18 | }
19 | return arr;
20 | }
21 |
22 | export default shellSort
23 |
--------------------------------------------------------------------------------
/examples/SortChallenge/src/algorithms/stoogeSort.js:
--------------------------------------------------------------------------------
1 | /*
2 | Придурковатая сортировка
3 | */
4 |
5 | const stoogeSort = (arr, l = 0, h = arr.length - 1) => {
6 | if (l >= h) {
7 | return arr;
8 | }
9 |
10 | // Если первый элемент меньше последнего, то меняем их местами
11 | if (arr[l] > arr[h]) {
12 | [arr[l], arr[h]] = [arr[h], arr[l]];
13 | }
14 |
15 | // Если в массиве больше двух элементов
16 | if (h - l + 1 > 2) {
17 | const t = Math.floor((h - l + 1) / 3);
18 |
19 | // Рекурсивно сортируем первые 2/3 элементов
20 | arr = stoogeSort(arr, l, h - t);
21 |
22 | // Рекурсивно сортируем последние 2/3 элементов
23 | arr = stoogeSort(arr, l + t, h);
24 |
25 | // Рекурсивно сортируем первые 2/3 элементов снова
26 | arr = stoogeSort(arr, l, h - t);
27 | }
28 |
29 | return arr;
30 | }
31 |
32 | export default stoogeSort
--------------------------------------------------------------------------------
/examples/SortChallenge/src/fonts/Tapestry-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/SortChallenge/src/fonts/Tapestry-Regular.ttf
--------------------------------------------------------------------------------
/examples/SortChallenge/src/images/background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/SortChallenge/src/images/background.jpg
--------------------------------------------------------------------------------
/examples/SortChallenge/src/styles/common.scss:
--------------------------------------------------------------------------------
1 | @import 'fonts.scss';
2 |
3 | body {
4 | margin: 0;
5 | padding: 0;
6 | }
7 |
8 | .page-header{
9 | text-align: center;
10 | font-family: 'Square Peg', cursive;
11 | font-size: 50px;
12 | }
13 |
14 | .image-block{
15 | display: flex;
16 | align-items: center;
17 | justify-content: center;
18 | }
--------------------------------------------------------------------------------
/examples/SortChallenge/src/styles/fonts.scss:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'Tapestry';
3 | src: local('Tapestry'), url(../fonts/Tapestry-Regular.ttf) format('truetype');
4 | }
5 |
6 | @import url('https://fonts.googleapis.com/css2?family=Square+Peg&display=swap');
--------------------------------------------------------------------------------
/examples/SortChallenge/src/styles/main.scss:
--------------------------------------------------------------------------------
1 | @import 'common.scss';
2 |
3 | .all-links {
4 | display: flex;
5 | align-items: center;
6 | justify-content: center;
7 | padding: 20px;
8 | user-select: none;
9 |
10 | a {
11 | padding: 20px;
12 | margin: 20px;
13 | background-color: #ddd;
14 | border-color: #00f;
15 | border-radius: 10px;
16 | min-width: 200px;
17 | text-align: center;
18 | text-decoration: none;
19 | color: black;
20 | font-weight: bold;
21 | font-size: 30px;
22 | font-family: Arial, Helvetica, sans-serif;
23 |
24 | &:hover{
25 | font-style: italic;
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/examples/SortChallenge/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import legacy from "@vitejs/plugin-legacy";
3 | import timeMarkPlugin from "./plugins/vite-plugin-timemark";
4 |
5 | export default defineConfig({
6 | base: '',
7 | build: {
8 | target: "es2017",
9 | outDir: "build",
10 | rollupOptions: {
11 | output: {
12 | assetFileNames: ({ name }) => {
13 | if (/\.(gif|jpe?g|png|svg)$/.test(name ?? "")) {
14 | return "assets/images/[name]-[hash][extname]";
15 | }
16 |
17 | if (/\.(ttf|otf|fnt|woff)$/.test(name ?? "")) {
18 | return "assets/fonts/[name]-[hash][extname]";
19 | }
20 |
21 | if (/\.css$/.test(name ?? "")) {
22 | return "assets/css/[name]-[hash][extname]";
23 | }
24 |
25 | return "assets/[name]-[hash][extname]";
26 | },
27 | },
28 | },
29 | },
30 | server: {
31 | port: 3000,
32 | host: "0.0.0.0",
33 | hmr: true,
34 | },
35 | plugins: [
36 | legacy({
37 | targets: ["defaults", "not IE 11"],
38 | }),
39 | timeMarkPlugin(),
40 | ],
41 | });
42 |
--------------------------------------------------------------------------------
/examples/Symbols/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Symbols examples
7 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/examples/Symbols/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "symbols",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "type": "module",
7 | "scripts": {
8 | "test": "echo \"Error: no test specified\" && exit 1",
9 | "start": "vite"
10 | },
11 | "keywords": [],
12 | "author": "",
13 | "license": "ISC",
14 | "devDependencies": {
15 | "vite": "^5.4.0"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/examples/Symbols/src/examples/example1.js:
--------------------------------------------------------------------------------
1 | const name = 'example1'
2 |
3 | const run = () => {
4 | const sym1 = Symbol();
5 | const sym2 = Symbol('description');
6 |
7 | console.clear()
8 | console.log(name)
9 |
10 | console.log(sym1);
11 | console.log(sym2);
12 | }
13 |
14 | export default {
15 | name,
16 | run,
17 | }
--------------------------------------------------------------------------------
/examples/Symbols/src/examples/example10.js:
--------------------------------------------------------------------------------
1 | const name = 'Symbol.toPrimitive'
2 |
3 | const run = () => {
4 | console.clear()
5 | console.log(name)
6 |
7 | const obj1 = {
8 | value: 10,
9 | name: 'obj1',
10 | }
11 | const obj2 = {
12 | value: 20,
13 | name: 'obj2',
14 | }
15 |
16 | console.log('obj1 * obj2', obj1 * obj2)
17 |
18 | const toPrimitive = function(hint){
19 | switch (hint) {
20 | case 'string':
21 | return this.name;
22 | case 'number':
23 | return this.value;
24 | default:
25 | return this.value;
26 | }
27 | };
28 |
29 | obj1[Symbol.toPrimitive] = toPrimitive
30 | obj2[Symbol.toPrimitive] = toPrimitive
31 |
32 | console.log('obj1 * obj2 with Symbol.toPrimitive', obj1 * obj2)
33 | console.log('obj1 * obj2 with Symbol.toPrimitive', `name=${obj1} name=${obj2}`)
34 | }
35 |
36 | export default {
37 | name,
38 | run,
39 | }
--------------------------------------------------------------------------------
/examples/Symbols/src/examples/example11.js:
--------------------------------------------------------------------------------
1 | const name = 'Symbol.toStringTag'
2 |
3 | const run = () => {
4 | console.clear()
5 | console.log(name)
6 |
7 | class CustomCollection {
8 | constructor(items) {
9 | this.items = items;
10 | }
11 |
12 | get [Symbol.toStringTag]() {
13 | return 'CustomCollection';
14 | }
15 | }
16 |
17 | const myCollection = new CustomCollection([1, 2, 3]);
18 |
19 | console.log('myCollection', `${myCollection}`)
20 |
21 | const obj = {
22 | [Symbol.toStringTag]: 'MySpecialObject'
23 | };
24 |
25 | console.log('MySpecialObject', `${obj}`)
26 |
27 |
28 | }
29 |
30 | export default {
31 | name,
32 | run,
33 | }
--------------------------------------------------------------------------------
/examples/Symbols/src/examples/example12.js:
--------------------------------------------------------------------------------
1 | const name = 'Symbol.species'
2 |
3 | const run = () => {
4 | console.clear()
5 | console.log(name)
6 |
7 | class MyArray extends Array {
8 | // static get [Symbol.species]() {
9 | // return Array;
10 | // }
11 | }
12 |
13 | const myArray = new MyArray(1, 2, 3, 4);
14 | const slicedArray = myArray.slice(1, 3);
15 |
16 | console.log('slicedArray instanceof MyArray', slicedArray instanceof MyArray);
17 | console.log('slicedArray instanceof Array', slicedArray instanceof Array);
18 | }
19 |
20 | export default {
21 | name,
22 | run,
23 | }
--------------------------------------------------------------------------------
/examples/Symbols/src/examples/example2.js:
--------------------------------------------------------------------------------
1 | const name = 'example2'
2 |
3 | const run = () => {
4 | const sym1a = Symbol();
5 | const sym1b = Symbol();
6 | const sym2a = Symbol('description');
7 | const sym2b = Symbol('description');
8 |
9 | console.clear()
10 | console.log(name)
11 |
12 | console.log('sym1', sym1a === sym1b);
13 | console.log('sym2', sym2a === sym2b);
14 | }
15 |
16 | export default {
17 | name,
18 | run,
19 | }
--------------------------------------------------------------------------------
/examples/Symbols/src/examples/example3.js:
--------------------------------------------------------------------------------
1 | const name = 'example3'
2 |
3 | const run = () => {
4 | const propName = Symbol('propName')
5 |
6 | const myObject = {
7 | [propName]: 'initial',
8 | setValue(data){
9 | this[propName] = data;
10 | },
11 | getValue(){
12 | return this[propName];
13 | },
14 | };
15 |
16 |
17 | console.clear();
18 | console.log(name);
19 |
20 | myObject.setValue(12345);
21 | console.log('myObject.getValue', myObject.getValue());
22 |
23 | console.log('myObject', myObject);
24 |
25 | console.log('JSON.stringify', JSON.stringify(myObject, null, 4));
26 | const keys = Object.keys(myObject)
27 | console.log('Object.keys', keys, keys.map((k) => myObject[k]));
28 |
29 | console.log("myObject[Symbol('propName')]", myObject[Symbol('propName')]);
30 | console.log("myObject['Symbol(propName)']", myObject['Symbol(propName)']);
31 |
32 | }
33 |
34 | export default {
35 | name,
36 | run,
37 | }
--------------------------------------------------------------------------------
/examples/Symbols/src/examples/example4.js:
--------------------------------------------------------------------------------
1 | const name = 'Symbol.iterator'
2 |
3 | const run = () => {
4 | const rangeFabric = (start, end, step) => ({
5 | start,
6 | end,
7 | [Symbol.iterator]() {
8 | return {
9 | current: this.start,
10 | last: this.end,
11 | next() {
12 | if (this.current <= this.last) {
13 | const value = this.current
14 | this.current += step
15 | return { done: false, value };
16 | } else {
17 | return { done: true };
18 | }
19 | }
20 | };
21 | }
22 | })
23 | const range = rangeFabric(1, 100, 1)
24 |
25 |
26 | console.clear()
27 | console.log(name)
28 | console.log(...range)
29 | }
30 |
31 | export default {
32 | name,
33 | run,
34 | }
--------------------------------------------------------------------------------
/examples/Symbols/src/examples/example5.js:
--------------------------------------------------------------------------------
1 | const name = 'Symbol.asyncIterator'
2 |
3 | const run = async () => {
4 | const asyncRangeFabric = (start, end, step) => ({
5 | start,
6 | end,
7 | [Symbol.asyncIterator]() {
8 | return {
9 | current: this.start,
10 | last: this.end,
11 | next: async function () {
12 | if (this.current <= this.last) {
13 | const value = this.current
14 | this.current += step
15 | await new Promise(resolve => setTimeout(resolve, 1000));
16 | return { done: false, value };
17 | } else {
18 | return { done: true };
19 | }
20 | }
21 | };
22 | }
23 | })
24 | const asyncRange = asyncRangeFabric(1, 100, 1)
25 |
26 |
27 | console.clear()
28 | console.log(name)
29 |
30 | for await (let value of asyncRange) {
31 | console.log(value);
32 | }
33 | }
34 |
35 | export default {
36 | name,
37 | run,
38 | }
--------------------------------------------------------------------------------
/examples/Symbols/src/examples/example6.js:
--------------------------------------------------------------------------------
1 | const name = 'Symbol.hasInstance'
2 |
3 | const run = () => {
4 | console.clear()
5 | console.log(name)
6 |
7 | class MyClass {
8 | static [Symbol.hasInstance](instance) {
9 | return 'customProperty' in instance;
10 | }
11 | }
12 |
13 | const obj1 = { customProperty: 123 };
14 | const obj2 = { anotherProperty: 456 };
15 | console.log('obj1', obj1);
16 | console.log('obj1 instanceof MyClass', obj1 instanceof MyClass);
17 | console.log('obj2', obj2);
18 | console.log('obj2 instanceof MyClass', obj2 instanceof MyClass);
19 | }
20 |
21 | export default {
22 | name,
23 | run,
24 | }
--------------------------------------------------------------------------------
/examples/Symbols/src/examples/example7.js:
--------------------------------------------------------------------------------
1 | const name = 'Symbol.isConcatSpreadable'
2 |
3 | const run = () => {
4 | console.clear()
5 | console.log(name)
6 |
7 | const arr1 = [1, 2, 3];
8 | const arr2 = [4, 5];
9 |
10 | console.log('arr1.concat(arr2)', arr1.concat(arr2));
11 |
12 | const obj = { 0: 'a', 1: 'b', length: 2 };
13 |
14 | console.log('arr1.concat(obj)', arr1.concat(obj));
15 |
16 |
17 | arr2[Symbol.isConcatSpreadable] = false;
18 | console.log('arr1.concat(arr2) Symbol.isConcatSpreadable === false', arr1.concat(arr2));
19 | obj[Symbol.isConcatSpreadable] = true;
20 | console.log('arr1.concat(obj) Symbol.isConcatSpreadable === true', arr1.concat(obj));
21 | }
22 |
23 | export default {
24 | name,
25 | run,
26 | }
--------------------------------------------------------------------------------
/examples/Symbols/src/examples/example8.js:
--------------------------------------------------------------------------------
1 | const name = 'Symbol.match'
2 |
3 | const run = () => {
4 | console.clear()
5 | console.log(name)
6 |
7 | class CustomMatcher {
8 | constructor(value) {
9 | this.value = value;
10 | }
11 |
12 | [Symbol.match](string) {
13 | const index = string.indexOf(this.value);
14 | return index === -1 ? { found: false} : {position: index, found: true, value: this.value};
15 | }
16 | }
17 |
18 | const matcher = new CustomMatcher('hello');
19 |
20 | const result1 = 'hello world'.match(matcher);
21 | console.log("'hello world'.match(matcher)", result1);
22 |
23 | const result2 = 'goodbye world'.match(matcher);
24 | console.log("'goodbye world'.match(matcher)", result2);
25 | }
26 |
27 | export default {
28 | name,
29 | run,
30 | }
--------------------------------------------------------------------------------
/examples/Symbols/src/examples/index.js:
--------------------------------------------------------------------------------
1 | import example1 from './example1'
2 | import example2 from './example2'
3 | import example3 from './example3'
4 | import example4 from './example4'
5 | import example5 from './example5'
6 | import example6 from './example6'
7 | import example7 from './example7'
8 | import example8 from './example8'
9 | import example9 from './example9'
10 | import example10 from './example10'
11 | import example11 from './example11'
12 | import example12 from './example12'
13 |
14 | export const examples = [
15 | example1,
16 | example2,
17 | example3,
18 | example4,
19 | example5,
20 | example6,
21 | example7,
22 | example8,
23 | example9,
24 | example10,
25 | example11,
26 | example12,
27 | ]
28 |
--------------------------------------------------------------------------------
/examples/Symbols/src/index.js:
--------------------------------------------------------------------------------
1 | import { examples } from './examples';
2 | const buttons = document.getElementById('buttons');
3 |
4 | if(Array.isArray(examples)){
5 | examples.forEach((example) => {
6 | const btn = document.createElement('button');
7 | btn.type = 'button';
8 | btn.textContent = example.name
9 | btn.addEventListener('click', example.run);
10 | buttons.appendChild(btn);
11 | })
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/examples/Symbols/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 |
3 | export default defineConfig({
4 | server: {
5 | port: 3000,
6 | host: '0.0.0.0'
7 | }
8 | })
--------------------------------------------------------------------------------
/examples/WasmRust/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wasmrust",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "type": "module",
7 | "scripts": {
8 | "dev": "vite",
9 | "test": "echo \"Error: no test specified\" && exit 1"
10 | },
11 | "keywords": [],
12 | "author": "",
13 | "license": "ISC",
14 | "devDependencies": {
15 | "vite": "6.0.6",
16 | "wasm_image_editor": "file:wasm_image_editor/pkg"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/examples/WasmRust/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 |
3 | export default defineConfig({
4 | server: {
5 | port: 3000,
6 | host: '0.0.0.0'
7 | }
8 | })
--------------------------------------------------------------------------------
/examples/WasmRust/wasm_image_editor/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "wasm_image_editor"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | [dependencies]
7 | wasm-bindgen = "0.2.99"
8 |
9 | [lib]
10 | crate-type = ["cdylib"]
11 |
12 | [profile.release]
13 | lto = true
14 |
15 |
--------------------------------------------------------------------------------
/examples/WebRTS/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "type": "node",
6 | "request": "launch",
7 | "name": "Launch Program",
8 | "skipFiles": [
9 | "/**"
10 | ],
11 | "runtimeExecutable": "/Users/easy/.nvm/versions/node/v22.15.0/bin/node",
12 | "program": "${workspaceFolder}/src/server/server.js"
13 | }
14 | ]
15 | }
--------------------------------------------------------------------------------
/examples/WebRTS/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite App
8 |
9 |
17 |
18 |
19 |
20 |
A simple way (no server needed)
21 |
To stream something
22 |
To subscribe to a stream
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/examples/WebRTS/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "webrts",
3 | "version": "1.0.0",
4 | "main": "server.js",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "preview": "vite preview",
10 | "server": "npm run build && node ./src/server/server.js"
11 | },
12 | "keywords": [],
13 | "author": "",
14 | "license": "ISC",
15 | "description": "",
16 | "dependencies": {
17 | "@fastify/cors": "^11.0.1",
18 | "@fastify/static": "^8.1.1",
19 | "@fastify/websocket": "^11.0.2",
20 | "express": "^5.1.0",
21 | "fastify": "^5.3.2",
22 | "ws": "^8.18.1"
23 | },
24 | "devDependencies": {
25 | "vite": "^6.3.3"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/examples/WebRTS/src/client/stream.js:
--------------------------------------------------------------------------------
1 | const peers = [];
2 |
3 | const createPeer = (streamId, role, signalHandler) => {
4 | const peer = new SimplePeer({
5 | initiator: role === 'streamer',
6 | trickle: false,
7 | });
8 |
9 | peer.on('signal', (data) => {
10 | signalHandler(data);
11 | });
12 |
13 | peer.on('stream', (stream) => {
14 | if (role === 'viewer') {
15 | const video = document.getElementById('video');
16 | video.srcObject = stream;
17 | }
18 | });
19 |
20 | peer.on('error', (err) => {
21 | console.error('Peer Error:', err);
22 | });
23 | peers.push(peer);
24 | return peer;
25 | };
26 |
27 | export { createPeer };
--------------------------------------------------------------------------------
/examples/WebRTS/src/utils.js:
--------------------------------------------------------------------------------
1 | export const getWebSocketAddress = () => {
2 | const wsProtocol = location.protocol === "https:" ? "wss://" : "ws://";
3 | const wsHost = location.host;
4 | const wsUrl = `${wsProtocol}${wsHost}/ws`;
5 | return wsUrl;
6 | };
7 |
--------------------------------------------------------------------------------
/examples/WebRTS/streamer.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Стример
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/examples/WebRTS/viewer.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Вьювер
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/examples/WebRTS/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 |
3 | export default defineConfig({
4 | server: {
5 | host: '0.0.0.0',
6 | port: 3000,
7 | },
8 | build: {
9 | rollupOptions: {
10 | input: {
11 | index: './index.html',
12 | streamer: './streamer.html',
13 | viewer: './viewer.html',
14 | simple: './simple.html',
15 | }
16 | }
17 | }
18 | })
--------------------------------------------------------------------------------
/examples/WebSocket/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "type": "node",
9 | "request": "launch",
10 | "name": "Launch Program",
11 | "skipFiles": [
12 | "/**"
13 | ],
14 | "runtimeExecutable": "/Users/easy/.nvm/versions/node/v22.15.0/bin/node",
15 | "program": "${workspaceFolder}/src/server/server.js"
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/examples/WebSocket/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Vite App
8 |
9 |
10 |
11 |
12 |
13 |
Display name:
14 |
15 |
16 |
17 |
21 |
22 |
23 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/examples/WebSocket/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "websocket",
3 | "private": true,
4 | "version": "0.0.1",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "vite build",
9 | "preview": "vite preview",
10 | "server": "node src/server.js"
11 | },
12 | "devDependencies": {
13 | "vite": "^6.3.1"
14 | },
15 | "dependencies": {
16 | "@fastify/websocket": "^11.0.2",
17 | "fastify": "^5.3.2"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/examples/WebSocket/src/client/websocket.js:
--------------------------------------------------------------------------------
1 | import { appConstants } from "../common/constants";
2 | import { sendToSocket } from "../common/utils";
3 |
4 | let ws;
5 |
6 | export const init = (id, {onOpen, onMessage, onError, onClose}) => {
7 | ws = new WebSocket(`ws://${appConstants.wsAddress}/ws?id=${id}`);
8 |
9 | ws.addEventListener('open', onOpen);
10 | ws.addEventListener('message', onMessage);
11 | ws.addEventListener('close', onClose);
12 | ws.addEventListener('error', onError);
13 | }
14 |
15 | export const sendMessage = (message) => {
16 | sendToSocket(ws, message);
17 | }
--------------------------------------------------------------------------------
/examples/WebSocket/src/common/constants.js:
--------------------------------------------------------------------------------
1 | export const appConstants = {
2 | message: {
3 | type: {
4 | setName: "setName",
5 | getUsers: "getUsers",
6 | sendMessage: "sendMessage",
7 | messageDelivered: "messageDelivered",
8 | usersList: "usersList",
9 | publicMessage: "publicMessage",
10 | },
11 | },
12 | wsAddress: 'localhost:3001',
13 | button: {
14 | type: {
15 | sendMessage: 'sendMessage'
16 | }
17 | }
18 | };
19 |
--------------------------------------------------------------------------------
/examples/WebSocket/src/server/server.js:
--------------------------------------------------------------------------------
1 | import Fastify from "fastify";
2 | import fastifyWebsocket from "@fastify/websocket";
3 | import { addStream } from "./streams.js";
4 |
5 | const fastify = Fastify({ logger: true});
6 | await fastify.register(fastifyWebsocket);
7 |
8 | fastify.register(async (fastify) => {
9 | fastify.get('/ws', {websocket: true}, (socket, req) => {
10 | let clientStreamId = req.query.id;
11 | addStream(clientStreamId, socket);
12 | })
13 | });
14 |
15 | fastify.listen({port: 3001, host: '0.0.0.0'}, (err) => {
16 | if(err){
17 | fastify.log.error(err)
18 | process.exit(1);
19 | }
20 | })
--------------------------------------------------------------------------------
/examples/WebSocket/src/server/utils.js:
--------------------------------------------------------------------------------
1 | export const parseServerMessage = (message) => {
2 | if (Buffer.isBuffer(message)) {
3 | const str = message.toString("utf-8");
4 | return JSON.parse(str);
5 | }
6 | };
7 |
--------------------------------------------------------------------------------
/examples/WebSocket/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 |
3 | export default defineConfig({
4 | server: {
5 | host: '0.0.0.0',
6 | port: 3000
7 | },
8 | })
--------------------------------------------------------------------------------
/examples/WebWorker/example2.js:
--------------------------------------------------------------------------------
1 | let worker;
2 |
3 | const onMessage = (e) => {
4 | if (e?.data) {
5 | document.querySelector("#result").textContent = JSON.stringify(e.data, null, 2);
6 | }
7 | };
8 |
9 | const reCreate = () => {
10 | if (worker) {
11 | worker.terminate();
12 | }
13 | const scriptText = document.querySelector("#textblock").value;
14 | const blob = new Blob([scriptText], { type: "text/javascript" });
15 | worker = new Worker(window.URL.createObjectURL(blob));
16 |
17 | worker.onmessage = onMessage;
18 | };
19 |
20 | const onClickTodo = () => {
21 | worker.postMessage({ type: "todo", id: 1 });
22 | };
23 | const onClickUser = () => {
24 | worker.postMessage({ type: "user", id: 2 });
25 | };
26 | const onClickRecreate = () => {
27 | reCreate()
28 | };
29 |
30 | document.querySelector("#btn1").addEventListener("click", onClickTodo);
31 | document.querySelector("#btn2").addEventListener("click", onClickUser);
32 | document.querySelector("#btn3").addEventListener("click", onClickRecreate);
33 |
34 | reCreate()
35 |
--------------------------------------------------------------------------------
/examples/WebWorker/index.js:
--------------------------------------------------------------------------------
1 | import './example1'
2 |
3 |
--------------------------------------------------------------------------------
/examples/WebWorker/index2.js:
--------------------------------------------------------------------------------
1 | import './example2'
2 |
3 |
--------------------------------------------------------------------------------
/examples/WebWorker/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "micromacro",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "scripts": {
6 | "start": "vite",
7 | "build": "vite build",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "devDependencies": {
14 | "vite": "^3.1.4"
15 | },
16 | "dependencies": {
17 | "esbuild-darwin-64": "^0.15.10",
18 | "esbuild": "^0.15.10",
19 | "function-bind": "^1.1.1",
20 | "has": "^1.0.3",
21 | "fsevents": "^2.3.2",
22 | "is-core-module": "^2.10.0",
23 | "picocolors": "^1.0.0",
24 | "nanoid": "^3.3.4",
25 | "path-parse": "^1.0.7",
26 | "source-map-js": "^1.0.2",
27 | "postcss": "^8.4.17",
28 | "resolve": "^1.22.1",
29 | "rollup": "^2.78.1",
30 | "supports-preserve-symlinks-flag": "^1.0.0"
31 | },
32 | "description": ""
33 | }
34 |
--------------------------------------------------------------------------------
/examples/WebWorker/vite.config.js:
--------------------------------------------------------------------------------
1 | import { resolve } from "path";
2 | import { defineConfig } from "vite";
3 |
4 | export default defineConfig({
5 | server: {
6 | host: "0.0.0.0",
7 | port: 3000,
8 | },
9 | build: {
10 | target: "es2017",
11 | outDir: "build",
12 | rollupOptions: {
13 | input: {
14 | main: resolve(__dirname, "./index.html"),
15 | main2: resolve(__dirname, "./index2.html"),
16 | },
17 | },
18 | },
19 | });
20 |
--------------------------------------------------------------------------------
/examples/WebWorker/webworker.js:
--------------------------------------------------------------------------------
1 | function answer(data) {
2 | postMessage(data);
3 | }
4 |
5 | const calculate = (data) => {
6 | if (data?.text) {
7 | const textArray = [...data.text];
8 | let result = "";
9 | while (textArray.length > 0) {
10 | const idx = Math.floor(Math.random() * textArray.length);
11 | result = result + textArray.splice(idx, 1)[0];
12 | }
13 | answer({ type: "result", result });
14 | return
15 | }
16 | answer({ type: "defailt", result: data });
17 | };
18 |
19 | onmessage = (event) => {
20 | if (event?.data) {
21 | calculate(event.data);
22 | } else {
23 | answer({ type: "defailt", result: event });
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/examples/WebWorker2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "atomicapi",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "vite.config.js",
6 | "scripts": {
7 | "start" : "vite",
8 | "build": "vite build",
9 | "test": "echo \"Error: no test specified\" && exit 1"
10 | },
11 | "keywords": [],
12 | "author": "",
13 | "license": "ISC",
14 | "devDependencies": {
15 | "vite": "^5.0.5"
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/examples/WebWorker2/scheme.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/WebWorker2/scheme.pdf
--------------------------------------------------------------------------------
/examples/WebWorker2/src/appConstants.js:
--------------------------------------------------------------------------------
1 | export const appConstants = {
2 | workers: {
3 | worker1: {
4 | name: 'worker1',
5 | expInput: 'exp1',
6 | inputIndex: 0,
7 | output: 'result1',
8 | },
9 | worker2: {
10 | name: 'worker2',
11 | expInput: 'exp2',
12 | inputIndex: 1,
13 | output: 'result2',
14 | },
15 | worker3: {
16 | name: 'worker3',
17 | expInput: 'exp3',
18 | inputIndex: 2,
19 | output: 'result3',
20 | },
21 | }
22 | }
--------------------------------------------------------------------------------
/examples/WebWorker2/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 |
3 | export default defineConfig({
4 | server: {
5 | host: '0.0.0.0',
6 | port: 3000,
7 | headers: {
8 | 'Cross-Origin-Opener-Policy': 'same-origin',
9 | 'Cross-Origin-Embedder-Policy': 'require-corp',
10 | }
11 | },
12 | })
--------------------------------------------------------------------------------
/examples/arrow-functions/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | build/
3 | dist/
4 | reports/
5 | raml/examples_local/
6 | .vscode/
7 | .idea/
8 | coverage/
9 | /yarn.lock
10 |
11 | .npmrc
12 |
--------------------------------------------------------------------------------
/examples/arrow-functions/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 | Arrow functions specifics
12 |
13 |
14 |
15 |
20 |
21 |
--------------------------------------------------------------------------------
/examples/arrow-functions/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "spa_example",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "vite",
8 | "build": "cross-env BUILD_TYPE=dev vite build",
9 | "serve": "vite preview --port 3000",
10 | "build-prod": "cross-env BUILD_TYPE=prod vite build",
11 | "server": "json-server --port 1111 ./db.json",
12 | "test": "echo \"Error: no test specified\" && exit 1"
13 | },
14 | "keywords": [],
15 | "author": "",
16 | "license": "ISC",
17 | "devDependencies": {
18 | "@vitejs/plugin-legacy": "^1.7.0",
19 | "cross-env": "^7.0.3",
20 | "sass": "^1.46.0",
21 | "vite": "^2.8.0",
22 | "vite-aliases": "^0.8.7"
23 | },
24 | "dependencies": {
25 | "route-parser": "0.0.5"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/examples/arrow-functions/src/example1.js:
--------------------------------------------------------------------------------
1 | import { printToDiv } from './tools'
2 |
3 | class Example {
4 | constructor (data){
5 | this.data = data
6 | }
7 | }
8 |
9 | const example1 = new Example('example1')
10 | const example2 = new Example('example2')
11 |
12 | const getData = function(){
13 | printToDiv(`getData ===> ${this.constructor.name} ${this.data}`)
14 | return this.data
15 | }
16 |
17 | example1.getData = getData
18 |
19 | example1.getData()
20 |
21 | example1.getData.call(example2)
22 |
23 | document.getElementById('button').addEventListener('click', example1.getData.bind(example1))
24 |
25 | setTimeout(example1.getData.bind(example1), 1000)
26 |
27 |
28 |
--------------------------------------------------------------------------------
/examples/arrow-functions/src/example2.js:
--------------------------------------------------------------------------------
1 | import { printToDiv } from './tools'
2 |
3 | class Example {
4 | constructor (data){
5 | this.data = data
6 | }
7 | getData(){
8 | printToDiv(`getData ===> ${this.constructor.name} ${this.data}`)
9 | return this.data
10 | }
11 | }
12 |
13 | const example1 = new Example('example1')
14 | const example2 = new Example('example2')
15 |
16 |
17 | example1.getData()
18 |
19 | example1.getData.call(example2)
20 |
21 | //document.getElementById('button').addEventListener('click', example1.getData)
22 | //document.getElementById('button').addEventListener('click', example1.getData.bind(example1))
23 | document.getElementById('button').addEventListener('click', example1.getData.bind(example2))
24 |
25 | setTimeout(example1.getData, 1000)
26 |
27 |
28 |
--------------------------------------------------------------------------------
/examples/arrow-functions/src/example3.js:
--------------------------------------------------------------------------------
1 | import { printToDiv } from './tools'
2 |
3 | class Example {
4 | constructor (data){
5 | this.data = data
6 | }
7 | getData = () => {
8 | printToDiv(`getData ===> ${this.constructor.name} ${this.data}`)
9 | return this.data
10 | }
11 | }
12 |
13 | const example1 = new Example('example1')
14 | const example2 = new Example('example2')
15 |
16 |
17 | example1.getData()
18 |
19 | example1.getData.call(example2)
20 |
21 | //document.getElementById('button').addEventListener('click', example1.getData)
22 | //document.getElementById('button').addEventListener('click', example1.getData.bind(example1))
23 | document.getElementById('button').addEventListener('click', example1.getData.bind(example2))
24 |
25 | setTimeout(example1.getData, 1000)
26 |
27 | class newExample extends Example{
28 | constructor(data){
29 | super(data)
30 | }
31 |
32 | getData = () => {
33 | const data = this.data
34 | printToDiv(`new Example getData ===> ${this.constructor.name} ${this.data}`)
35 | return data
36 | }
37 | }
38 |
39 | const example3 = new newExample('example2')
40 |
41 |
42 | example3.getData()
--------------------------------------------------------------------------------
/examples/arrow-functions/src/example5.js:
--------------------------------------------------------------------------------
1 | import { printToDiv } from './tools'
2 |
3 | const Example = {
4 | data: 'Example5',
5 | init(){
6 | this.getData = () => {
7 | if(this){
8 | printToDiv(`getData ===> ${this.constructor.name} ${this.data}`)
9 | return this.data
10 | } else {
11 | printToDiv(`getData ===> I don't see any "this" here!`)
12 | }
13 | }
14 | },
15 | }
16 |
17 | Example.init()
18 | Example.getData()
19 | Example.getData.call({data: 'bla-bla-bla'})
20 |
21 | document.getElementById('button').addEventListener('click', Example.getData.bind({data: 'bla-bla-bla'}))
22 |
23 | setTimeout(Example.getData, 1000)
24 |
25 |
26 |
--------------------------------------------------------------------------------
/examples/arrow-functions/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/arrow-functions/src/favicon.ico
--------------------------------------------------------------------------------
/examples/arrow-functions/src/index.js:
--------------------------------------------------------------------------------
1 | //import './example1'
2 | //import './example2'
3 | import './example3'
4 | //import './example4'
5 | //import './example5'
6 |
--------------------------------------------------------------------------------
/examples/arrow-functions/src/tools.js:
--------------------------------------------------------------------------------
1 | export const printToDiv = (data) => {
2 | const rootDiv = document.getElementById('content')
3 | const div = document.createElement('div')
4 | div.textContent = `${data}`
5 | if(rootDiv){
6 | rootDiv.appendChild(div)
7 | }
8 | }
9 |
10 | export default {
11 | printToDiv
12 | }
--------------------------------------------------------------------------------
/examples/arrow-functions/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import { ViteAliases } from "vite-aliases";
3 | import legacy from "@vitejs/plugin-legacy"
4 |
5 | export default defineConfig({
6 | build: {
7 | target: 'es2017',
8 | outDir: 'build',
9 | },
10 | server: {
11 | port: 3000,
12 | host: '0.0.0.0',
13 | hmr: true,
14 | },
15 | plugins: [
16 | ViteAliases(),
17 | legacy({
18 | targets: ['defaults', 'not IE 11'],
19 | })
20 | ],
21 | })
--------------------------------------------------------------------------------
/examples/drag-n-drop/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules/
--------------------------------------------------------------------------------
/examples/drag-n-drop/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "WebPackHotReload",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "webpack serve --hot --open",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "devDependencies": {
14 | "webpack": "^5.64.3",
15 | "webpack-cli": "^4.9.1",
16 | "webpack-dev-server": "^4.5.0"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/examples/drag-n-drop/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Hot reload
5 |
6 |
7 | Hi here!
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/examples/drag-n-drop/src/components/cell.js:
--------------------------------------------------------------------------------
1 | const Cell = (data) => {
2 | const cell = document.createElement('div')
3 | cell.style.padding = '10px'
4 | cell.textContent = data
5 | cell.style.border = "1px solid #CCC"
6 | cell.style.width = '25%'
7 | return cell
8 | }
9 |
10 | export default Cell
--------------------------------------------------------------------------------
/examples/drag-n-drop/src/components/data.json:
--------------------------------------------------------------------------------
1 | [
2 | { "name": "user1", "salary": 1000, "position": "dev", "department": "dep1"},
3 | { "name": "user2", "salary": 1000, "position": "acc", "department": "dep1"},
4 | { "name": "user3", "salary": 2000, "position": "dev", "department": "dep1"},
5 | { "name": "user4", "salary": 1000, "position": "man", "department": "dep2"},
6 | { "name": "user5", "salary": 3000, "position": "dev", "department": "dep2"},
7 | { "name": "user6", "salary": 3000, "position": "dev", "department": "dep3"},
8 | { "name": "user7", "salary": 1000, "position": "acc", "department": "dep4"},
9 | { "name": "user8", "salary": 1500, "position": "qa", "department": "dep4"},
10 | { "name": "user9", "salary": 1000, "position": "qa", "department": "dep4"},
11 | { "name": "user10", "salary": 4500, "position": "dev", "department": "dep10"},
12 | { "name": "user11", "salary": 1500, "position": "dev", "department": "dep10"},
13 | { "name": "user12", "salary": 1060, "position": "dev", "department": "dep10"}
14 |
15 | ]
16 |
17 |
--------------------------------------------------------------------------------
/examples/drag-n-drop/src/components/row.js:
--------------------------------------------------------------------------------
1 | import Cell from './cell'
2 |
3 | let DraggingElement = null
4 |
5 | function onDragStart(e){
6 | console.log('onDragStart')
7 | DraggingElement = this
8 | }
9 |
10 | function onDrop(e){
11 | console.log('onDrop')
12 | const target = this
13 | const source = DraggingElement
14 | target.parentElement.insertBefore(source, target.nextSibling)
15 | }
16 |
17 | function onDragOver(e){
18 | e.preventDefault()
19 | return false;
20 | }
21 |
22 |
23 |
24 | const Row = (rowData) => {
25 | const row = document.createElement('div')
26 | row.style.display = 'flex'
27 | row.style.justifyContent = 'space-between'
28 | row.draggable = true;
29 |
30 | Object.keys(rowData).forEach(key => {
31 | const d = rowData[key]
32 | row.appendChild(Cell(d))
33 | });
34 | row.addEventListener('dragstart', onDragStart)
35 | row.addEventListener('drop', onDrop)
36 | row.addEventListener('dragover', onDragOver)
37 | return row
38 | }
39 |
40 | export default Row
--------------------------------------------------------------------------------
/examples/drag-n-drop/src/components/table.js:
--------------------------------------------------------------------------------
1 | import Row from './row'
2 |
3 |
4 | const Table = (tableData) => {
5 | const table = document.createElement('div')
6 | table.style.padding = '10px'
7 | table.style.border = "1px solid #CCC"
8 |
9 | tableData.forEach(row => {
10 | table.appendChild(Row(row))
11 | });
12 |
13 | return table
14 | }
15 |
16 | export default Table
--------------------------------------------------------------------------------
/examples/drag-n-drop/src/main.js:
--------------------------------------------------------------------------------
1 | import data from './components/data.json'
2 | import Table from './components/table'
3 |
4 |
5 | function init(){
6 | const table = Table(data);
7 |
8 | document.querySelector('body').appendChild(table)
9 |
10 | const div = document.getElementById('content')
11 | div.textContent = 'Bla bla bla!!!';
12 | }
13 |
14 | init()
--------------------------------------------------------------------------------
/examples/drag-n-drop/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 |
3 | module.exports = {
4 | mode: 'development',
5 | entry: './src/main.js',
6 | output: {
7 | path: __dirname + '/public',
8 | filename: 'bandle.js'
9 | },
10 | devServer: {
11 | port: 5000,
12 | static: './public',
13 | hot: true
14 | }
15 | }
--------------------------------------------------------------------------------
/examples/generator/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Generator
7 |
13 |
14 |
15 |
16 | - example 1
17 | - example 2
18 | - example 3
19 | - example 4
20 | - example 5
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/examples/generator/index1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Generator
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/examples/generator/index2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Generator
7 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/examples/generator/index3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Generator
7 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/examples/generator/index4.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Generator
7 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/examples/generator/index5.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Generator
7 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/examples/generator/src/generator1.js:
--------------------------------------------------------------------------------
1 | export function* GetGenerator(text){
2 | for (let i=0; i < 10; i++){
3 | yield `${text} ${i+1}`
4 | }
5 | }
--------------------------------------------------------------------------------
/examples/generator/src/generator3.js:
--------------------------------------------------------------------------------
1 | export function* GetGenerator(){
2 | for (let i=0; i < 10; i++){
3 | yield `${this.name} ${i+1}`
4 | }
5 | }
--------------------------------------------------------------------------------
/examples/generator/src/generator4.js:
--------------------------------------------------------------------------------
1 | import {GetGenerator} from './generator1.js'
2 |
3 | export function* ManyGenerators(){
4 | yield* GetGenerator('AAAAA 1')
5 | yield* GetGenerator('BBBBB 2')
6 | yield* GetGenerator('CCCCC 3')
7 | }
--------------------------------------------------------------------------------
/examples/generator/src/generator5.js:
--------------------------------------------------------------------------------
1 | async function* GetGenerator() {
2 | let query;
3 | while (true) {
4 | if (query) {
5 | query = yield await fetch(`https://jsonplaceholder.typicode.com/${query}`).then((res) => res.json());
6 | } else {
7 | query = yield null;
8 | }
9 | }
10 | }
11 |
12 | const init = () => {
13 | const gen = GetGenerator()
14 | gen.next()
15 |
16 | return {
17 | getData: async (query) => {
18 | const data = await gen.next(query)
19 | if(!data.done){
20 | return data.value
21 | }
22 | },
23 | stop: (data) => {
24 | gen.return(data)
25 | },
26 | error: () => {
27 | gen.throw(new Error('it is an error'))
28 | }
29 | }
30 | }
31 |
32 | export default init
33 |
--------------------------------------------------------------------------------
/examples/generator/src/index1.js:
--------------------------------------------------------------------------------
1 | import {GetGenerator} from './generator1.js'
2 |
3 | const output = document.querySelector('.output')
4 | if(output){
5 | const gen = GetGenerator('Iteration')
6 | let data = gen.next()
7 | while(!data.done){
8 | const div = document.createElement('div')
9 | div.textContent = data.value
10 | output.appendChild(div)
11 | data = gen.next()
12 | }
13 | }
--------------------------------------------------------------------------------
/examples/generator/src/index2.js:
--------------------------------------------------------------------------------
1 | import { GetGenerator } from "./generator1.js";
2 |
3 | const output = document.querySelector(".output");
4 | if (output) {
5 | const gen = GetGenerator('Like Array')
6 | const data = [...gen]
7 | data.forEach((value) => {
8 | const div = document.createElement("div");
9 | div.textContent = value;
10 | output.appendChild(div);
11 | });
12 | }
13 |
--------------------------------------------------------------------------------
/examples/generator/src/index3.js:
--------------------------------------------------------------------------------
1 | import { GetGenerator } from "./generator3.js";
2 |
3 | const output = document.querySelector(".output");
4 | if (output) {
5 |
6 | const IterableObject = {
7 | name: 'IterableObject',
8 | [Symbol.iterator]: GetGenerator
9 | }
10 |
11 | const data = [...IterableObject]
12 | data.forEach((value) => {
13 | const div = document.createElement("div");
14 | div.textContent = value;
15 | output.appendChild(div);
16 | });
17 | }
18 |
--------------------------------------------------------------------------------
/examples/generator/src/index4.js:
--------------------------------------------------------------------------------
1 | import { ManyGenerators } from "./generator4.js";
2 |
3 | const output = document.querySelector(".output");
4 | if (output) {
5 | const data = [...ManyGenerators()]
6 | data.forEach((value) => {
7 | const div = document.createElement("div");
8 | div.textContent = value;
9 | output.appendChild(div);
10 | });
11 | }
12 |
--------------------------------------------------------------------------------
/examples/generator/src/index5.js:
--------------------------------------------------------------------------------
1 | import init from "./generator5.js";
2 |
3 | const dataHub = init();
4 |
5 | const output = document.querySelector(".output");
6 |
7 | const getData = async (query) => {
8 | const data = await dataHub.getData(query);
9 | if (data) {
10 | data.forEach((row) => {
11 | const div = document.createElement("div");
12 | div.className = "row";
13 |
14 | div.innerHTML = Object.entries(row)
15 | .map(([key, value]) => {
16 | if(typeof(value) !== 'object'){
17 | return `${value}
`;
18 | }
19 | return ''
20 | })
21 | .join("");
22 |
23 | output.appendChild(div);
24 | });
25 | }
26 | };
27 |
28 | document.querySelector(".buttons").addEventListener("click", (e) => {
29 | if(e.target.hasAttribute('data')){
30 | output.innerHTML = '';
31 | const data = e.target.getAttribute('data')
32 | if(data === 'stop'){
33 | dataHub.stop()
34 | } else if(data === 'error'){
35 | dataHub.error()
36 | } else{
37 | getData(data)
38 | }
39 | }
40 | e.stopPropagation()
41 | });
42 |
--------------------------------------------------------------------------------
/examples/macro-micro/example1.js:
--------------------------------------------------------------------------------
1 |
2 | const doIt = (text) => () => console.log(text);
3 |
4 | const startMacro = (func) => {
5 | setTimeout(func);
6 | };
7 |
8 | const startMicro = (func) => {
9 | queueMicrotask(func);
10 | };
11 |
12 | const onClick = () => {
13 | for (let i = 0; i < 10; i++) {
14 | doIt("macro 1 " + i)();
15 | startMacro(doIt("macro 2 - " + i));
16 |
17 | startMicro(doIt("> MICRO - " + i));
18 |
19 | Promise.resolve().then(doIt("promise 4 - " + i));
20 |
21 | fetch('https://jsonplaceholder.typicode.com/todos/1').then(doIt("promise fetch - " + i))
22 |
23 | // startMicro(()=>fetch('https://jsonplaceholder.typicode.com/todos/1')
24 | // .then(doIt("promise fetch micro - " + i)))
25 |
26 | const p = new Promise((resolve) => {
27 | setTimeout(()=>resolve('ok'), 5000)
28 | })
29 | p.then(doIt("promise with 5sec delay - " + i))
30 | }
31 |
32 | };
33 |
34 | document.querySelector("#btn").addEventListener("click", onClick);
--------------------------------------------------------------------------------
/examples/macro-micro/example2.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | const onClick = () => {
4 | const text = document.querySelector("#textblock").value;
5 | const textArray = [...text];
6 |
7 | document.querySelector("#textblock").value = ''
8 | while (textArray.length > 0) {
9 | const idx = Math.floor(Math.random() * textArray.length);
10 | document.querySelector("#textblock").value = document.querySelector("#textblock").value + textArray.splice(idx, 1)[0]
11 | }
12 |
13 | };
14 |
15 | document.querySelector("#btn").addEventListener("click", onClick);
--------------------------------------------------------------------------------
/examples/macro-micro/example3.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | const doStep = (textArray) => {
4 | let counter = 0
5 | while (textArray.length > 0 && counter < 10) {
6 | const idx = Math.floor(Math.random() * textArray.length);
7 | document.querySelector("#textblock").value = document.querySelector("#textblock").value + textArray.splice(idx, 1)[0]
8 | counter++
9 | }
10 | if(textArray.length){
11 | setTimeout(()=>doStep(textArray))
12 | } else {
13 | console.log('done!')
14 | }
15 | console.log(textArray.length)
16 | }
17 |
18 | const onClick = () => {
19 | const text = document.querySelector("#textblock").value;
20 | const textArray = [...text];
21 |
22 | document.querySelector("#textblock").value = ''
23 | setTimeout(()=>doStep(textArray))
24 | };
25 |
26 | document.querySelector("#btn").addEventListener("click", onClick);
--------------------------------------------------------------------------------
/examples/macro-micro/index.js:
--------------------------------------------------------------------------------
1 | import './example1'
2 |
3 |
--------------------------------------------------------------------------------
/examples/macro-micro/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "micromacro",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "vite",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "devDependencies": {
14 | "vite": "^3.1.4"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/examples/macro-micro/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 |
3 |
4 | export default defineConfig({
5 | server: {
6 | host: '0.0.0.0',
7 | port: 3000,
8 | }
9 | })
--------------------------------------------------------------------------------
/examples/pagination/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Pagination examples
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/examples/pagination/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "easy-it-vitejs-setup",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "vite",
8 | "build": "vite build",
9 | "serve": "vite preview --port 3000",
10 | "test": "echo \"Error: no test specified\" && exit 1"
11 | },
12 | "keywords": [],
13 | "browserslist": [
14 | "cover 99.5%"
15 | ],
16 | "author": "",
17 | "license": "ISC",
18 | "devDependencies": {
19 | "@vitejs/plugin-legacy": "^4.0.1",
20 | "sass": "^1.58.3",
21 | "vite": "^4.1.4"
22 | },
23 | "dependencies": {
24 | "@fastify/express": "^2.3.0",
25 | "cors": "^2.8.5",
26 | "fastify": "^4.22.2"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/examples/pagination/server.mjs:
--------------------------------------------------------------------------------
1 | import fastify from "fastify";
2 | import cors from "cors";
3 | import express from "@fastify/express";
4 |
5 | const app = fastify();
6 | app.register(express).then(() => {
7 | app.use(cors());
8 | const address = "0.0.0.0";
9 | const port = 4000;
10 | try {
11 | app.get("/todos", (req, res) => {
12 | const { _start, _limit } = req.query;
13 | fetch(`https://jsonplaceholder.typicode.com/todos?_start=${_start}&_limit=${_limit}`)
14 | .then((response) => response.json())
15 | .then((todos) => {
16 | setTimeout(() => {
17 | res.send(todos);
18 | }, 2000);
19 | })
20 | .catch((e) => console.log(e));
21 | });
22 |
23 | app.listen({ address, port }, function (err, address) {
24 | if (err) {
25 | console.log(err);
26 | process.exit(1);
27 | }
28 | console.log(`server listening on ${address}`);
29 | });
30 | } catch (err) {
31 | console.log(err);
32 | process.exit(1);
33 | }
34 | });
35 |
--------------------------------------------------------------------------------
/examples/pagination/src/fonts/Tapestry-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/pagination/src/fonts/Tapestry-Regular.ttf
--------------------------------------------------------------------------------
/examples/pagination/src/images/background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/pagination/src/images/background.jpg
--------------------------------------------------------------------------------
/examples/pagination/src/js/api.js:
--------------------------------------------------------------------------------
1 | import appConstants from "./constants";
2 |
3 | export const fetchTodos = ({start}, options = {}) => {
4 | return new Promise((resolve, reject) => {
5 | fetch(`http://localhost:4000/todos?_start=${start}&_limit=${appConstants.pageLimit}`, options)
6 | .then((response) => response.json())
7 | .then(resolve)
8 | .catch(reject);
9 | });
10 | };
11 |
--------------------------------------------------------------------------------
/examples/pagination/src/js/constants.js:
--------------------------------------------------------------------------------
1 | const appConstants = {
2 | buttons: {
3 | example1: "example1",
4 | example2: "example2",
5 | example3: "example3",
6 | example4: "example4",
7 | },
8 | pageLimit: 15,
9 | };
10 |
11 | export default appConstants;
12 |
--------------------------------------------------------------------------------
/examples/pagination/src/js/example1.js:
--------------------------------------------------------------------------------
1 | import { fetchTodos } from "./api";
2 | import { createToDo } from "./todo";
3 |
4 | const example = (targetEl, start = 0) => {
5 | fetchTodos({start})
6 | .then((todos) => {
7 | todos.forEach((todo) => {
8 | targetEl.appendChild(createToDo(todo));
9 | });
10 | })
11 | .catch((e) => console.log(e));
12 | };
13 |
14 | export default example;
15 |
--------------------------------------------------------------------------------
/examples/pagination/src/js/example2.js:
--------------------------------------------------------------------------------
1 | import { fetchTodos } from "./api";
2 | import { createToDo } from "./todo";
3 |
4 | let timeout = null;
5 |
6 | const example = (targetEl, start = 0) => {
7 | if (timeout) {
8 | clearTimeout(timeout);
9 | timeout = null;
10 | }
11 | timeout = setTimeout(() => {
12 | fetchTodos({start})
13 | .then((todos) => {
14 | todos.forEach((todo) => {
15 | targetEl.appendChild(createToDo(todo));
16 | });
17 | timeout = null;
18 | })
19 | .catch((e) => console.log(e));
20 | }, 1000);
21 | };
22 |
23 | export default example;
24 |
--------------------------------------------------------------------------------
/examples/pagination/src/js/example3.js:
--------------------------------------------------------------------------------
1 | import { fetchTodos } from "./api";
2 | import { createToDo } from "./todo";
3 |
4 | let timeout = null;
5 |
6 | const example = (targetEl, start = 0) => {
7 | if (timeout) {
8 | return;
9 | }
10 | timeout = setTimeout(() => {
11 | timeout = null;
12 | }, 1000);
13 |
14 | fetchTodos({ start })
15 | .then((todos) => {
16 | todos.forEach((todo) => {
17 | targetEl.appendChild(createToDo(todo));
18 | });
19 | })
20 | .catch((e) => console.log(e));
21 | };
22 |
23 | export default example;
24 |
--------------------------------------------------------------------------------
/examples/pagination/src/js/example4.js:
--------------------------------------------------------------------------------
1 | import { fetchTodos } from "./api";
2 | import { createToDo } from "./todo";
3 |
4 | let controller;
5 |
6 | const example = (targetEl, start = 0) => {
7 | if (controller && !controller.signal.aborted) {
8 | controller.abort();
9 | }
10 |
11 | controller = new AbortController();
12 | fetchTodos({ start }, { signal: controller.signal })
13 | .then((todos) => {
14 | todos.forEach((todo) => {
15 | targetEl.appendChild(createToDo(todo));
16 | });
17 | controller = null;
18 | })
19 | .catch((e) => console.log(e));
20 | };
21 |
22 | export default example;
23 |
--------------------------------------------------------------------------------
/examples/pagination/src/js/todo.js:
--------------------------------------------------------------------------------
1 | export const createToDo = (data) => {
2 | const todo = document.createElement('article')
3 | todo.className = 'todo'
4 | const textId = document.createElement('p')
5 | textId.className = 'todo-id'
6 | textId.textContent = data.id
7 | todo.appendChild(textId)
8 |
9 | const text = document.createElement('p')
10 | text.className = 'todo-text'
11 | text.textContent = data.title
12 | todo.appendChild(text)
13 | return todo
14 | }
15 |
--------------------------------------------------------------------------------
/examples/pagination/src/styles/common.scss:
--------------------------------------------------------------------------------
1 | @import 'fonts.scss';
2 |
3 | body, * {
4 | margin: 0;
5 | padding: 0;
6 | }
7 |
8 | .page-header{
9 | text-align: center;
10 | font-family: 'Square Peg', cursive;
11 | font-size: 50px;
12 | }
13 |
14 | .image-block{
15 | display: flex;
16 | align-items: center;
17 | justify-content: center;
18 | }
--------------------------------------------------------------------------------
/examples/pagination/src/styles/fonts.scss:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: 'Tapestry';
3 | src: local('Tapestry'), url(../fonts/Tapestry-Regular.ttf) format('truetype');
4 | }
5 |
6 | @import url('https://fonts.googleapis.com/css2?family=Square+Peg&display=swap');
--------------------------------------------------------------------------------
/examples/pagination/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import legacy from "@vitejs/plugin-legacy";
3 | import timeMarkPlugin from "./plugins/vite-plugin-timemark";
4 |
5 | export default defineConfig({
6 | build: {
7 | target: "es2017",
8 | outDir: "build",
9 | rollupOptions: {
10 | output: {
11 | assetFileNames: ({ name }) => {
12 | if (/\.(gif|jpe?g|png|svg)$/.test(name ?? "")) {
13 | return "assets/images/[name]-[hash][extname]";
14 | }
15 |
16 | if (/\.(ttf|otf|fnt|woff)$/.test(name ?? "")) {
17 | return "assets/fonts/[name]-[hash][extname]";
18 | }
19 |
20 | if (/\.css$/.test(name ?? "")) {
21 | return "assets/css/[name]-[hash][extname]";
22 | }
23 |
24 | return "assets/[name]-[hash][extname]";
25 | },
26 | },
27 | },
28 | },
29 | server: {
30 | port: 3000,
31 | host: "0.0.0.0",
32 | hmr: true,
33 | },
34 | plugins: [
35 | legacy({
36 | targets: ["defaults", "not IE 11"],
37 | }),
38 | timeMarkPlugin(),
39 | ],
40 | });
41 |
--------------------------------------------------------------------------------
/examples/redux1/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules/
--------------------------------------------------------------------------------
/examples/redux1/README.md:
--------------------------------------------------------------------------------
1 | # Пример как можно работать с Redux на чистом JavaScript
2 |
3 | ## Как пользоваться:
4 |
5 | npm install
6 |
7 | npm run start
8 |
9 |
10 |
11 | ## Полезные ссылки
12 |
13 | Самый правильный способ установки node и npm, настоятельно рекомендую устанавливать только так, это спасет Вас от лишних проблем в будущем.
14 |
15 | https://youtu.be/gP4OPx2vBoc
16 |
17 | Как настроить сборку проекта с помощью webpack
18 |
19 | https://youtu.be/unEl3Hezwpw
20 |
21 | Как настроить горячую перезагрузку (hot reloading) с помощью webpack
22 |
23 | https://youtu.be/oOpzkF2nU0s
24 |
25 |
--------------------------------------------------------------------------------
/examples/redux1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "WebPackHotReload",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "webpack serve --hot --open",
8 | "test": "echo \"Error: no test specified\" && exit 1"
9 | },
10 | "keywords": [],
11 | "author": "",
12 | "license": "ISC",
13 | "devDependencies": {
14 | "webpack": "^5.64.3",
15 | "webpack-cli": "^4.9.1",
16 | "webpack-dev-server": "^4.5.0"
17 | },
18 | "dependencies": {
19 | "redux": "^4.1.2"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/examples/redux1/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Redux
5 |
6 |
7 | Simple redux example
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/redux1/src/data/data.json:
--------------------------------------------------------------------------------
1 | [
2 | { "id": "100", "name": "user1", "salary": 1000, "position": "dev", "department": "dep1"},
3 | { "id": "200", "name": "user2", "salary": 1000, "position": "acc", "department": "dep1"},
4 | { "id": "300", "name": "user3", "salary": 2000, "position": "dev", "department": "dep1"},
5 | { "id": "400", "name": "user4", "salary": 1000, "position": "man", "department": "dep2"},
6 | { "id": "500", "name": "user5", "salary": 3000, "position": "dev", "department": "dep2"},
7 | { "id": "600", "name": "user6", "salary": 3000, "position": "dev", "department": "dep3"},
8 | { "id": "700", "name": "user7", "salary": 1000, "position": "acc", "department": "dep4"},
9 | { "id": "800", "name": "user8", "salary": 1500, "position": "qa", "department": "dep4"},
10 | { "id": "900", "name": "user9", "salary": 1000, "position": "qa", "department": "dep4"},
11 | { "id": "101", "name": "user10", "salary": 4500, "position": "dev", "department": "dep10"},
12 | { "id": "102", "name": "user11", "salary": 1500, "position": "dev", "department": "dep10"},
13 | { "id": "103", "name": "user12", "salary": 1060, "position": "dev", "department": "dep10"}
14 |
15 | ]
16 |
17 |
--------------------------------------------------------------------------------
/examples/redux1/src/main.js:
--------------------------------------------------------------------------------
1 | import data from './data/data.json'
2 | import Table from './components/table'
3 | import store from './redux/store'
4 | import {INIT_STATE} from './redux/actions'
5 |
6 | function init(){
7 | const table = new Table(data, true);
8 | const table2 = new Table(data, false);
9 | document.querySelector('#content').appendChild(table.element)
10 | document.querySelector('#content').appendChild(table2.element)
11 | store.dispatch({ type: INIT_STATE, payload: data })
12 | }
13 |
14 | init()
--------------------------------------------------------------------------------
/examples/redux1/src/redux/actions.js:
--------------------------------------------------------------------------------
1 | export const INIT_STATE = 'INIT_STATE'
2 | export const CHANGE_CELL = 'CHANGE_CELL'
3 | export const CHANGE_ORDER = 'CHANGE_ORDER'
--------------------------------------------------------------------------------
/examples/redux1/src/redux/reducer.js:
--------------------------------------------------------------------------------
1 | import * as ACTIONS from './actions'
2 |
3 | const Reducer = (state = [], action) => {
4 | switch(action.type){
5 | case ACTIONS.INIT_STATE: {
6 | return [
7 | ...action.payload
8 | ]
9 | }
10 | case ACTIONS.CHANGE_CELL: {
11 | const { id, key, data } = action.payload
12 | const newState = state.map(user => {
13 | if(user.id === id){
14 | user[key] = data
15 | }
16 | return {
17 | ...user
18 | }
19 | })
20 | return newState
21 | }
22 |
23 | case ACTIONS.CHANGE_ORDER: {
24 | const { idSource, idTarget } = action.payload
25 | return [ ...state ]
26 | }
27 | default: {
28 | return state
29 | }
30 | }
31 | }
32 |
33 | export default Reducer
--------------------------------------------------------------------------------
/examples/redux1/src/redux/store.js:
--------------------------------------------------------------------------------
1 | import { createStore } from "redux"
2 | import Reducer from './reducer'
3 |
4 | const store = createStore(Reducer, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__())
5 |
6 | export default store
--------------------------------------------------------------------------------
/examples/redux1/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 |
3 | module.exports = {
4 | mode: 'development',
5 | entry: './src/main.js',
6 | output: {
7 | path: __dirname + '/public',
8 | filename: 'bandle.js'
9 | },
10 | devServer: {
11 | port: 5000,
12 | static: './public',
13 | hot: true
14 | }
15 | }
--------------------------------------------------------------------------------
/examples/snowfall_css/img/background1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/snowfall_css/img/background1.png
--------------------------------------------------------------------------------
/examples/snowfall_css/img/background2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/snowfall_css/img/background2.png
--------------------------------------------------------------------------------
/examples/snowfall_css/img/background3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/snowfall_css/img/background3.png
--------------------------------------------------------------------------------
/examples/snowfall_css/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Snow Fall
5 |
6 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/examples/spa/bonus1/REST_server/mongo-config.conf:
--------------------------------------------------------------------------------
1 | systemLog:
2 | destination: file
3 | path: /usr/local/var/log/mongodb/mongo.log
4 | logAppend: true
5 | storage:
6 | dbPath: /usr/local/var/mongodb
7 | net:
8 | bindIp: 127.0.0.1, ::1
9 | ipv6: true
10 |
--------------------------------------------------------------------------------
/examples/spa/bonus1/REST_server/mongodb/fake.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/easy-linux/VanillaJS/669a17e27d0c46968f93ab14dade4762110e006d/examples/spa/bonus1/REST_server/mongodb/fake.txt
--------------------------------------------------------------------------------
/examples/spa/bonus1/REST_server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "RESTapi",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "mongo-start": "mongod --config ./mongo-config.conf --dbpath ./mongodb --logpath ./mongo.log",
9 | "generate": "node ./scripts/generateDb.js",
10 | "server": "concurrently \"npm run mongo-start\" \"npm run generate\" \"node ./server.js\""
11 | },
12 | "keywords": [],
13 | "author": "",
14 | "license": "ISC",
15 | "dependencies": {
16 | "@fastify/express": "^1.1.0",
17 | "@fastify/jwt": "^5.0.1",
18 | "@fastify/mongodb": "^5.0.0",
19 | "@fastify/static": "^5.0.2",
20 | "@fastify/swagger": "^6.0.1",
21 | "cors": "^2.8.5",
22 | "dns-prefetch-control": "^0.3.0",
23 | "fastify": "^3.29.0",
24 | "fastify-jwt": "^4.2.0",
25 | "fastify-mysql": "^2.2.0",
26 | "fastify-swagger": "^5.2.0",
27 | "frameguard": "^4.0.0",
28 | "hide-powered-by": "^1.1.0",
29 | "hsts": "^2.2.0",
30 | "ienoopen": "^1.1.0",
31 | "joi-to-json": "^2.2.4",
32 | "x-xss-protection": "^2.0.0"
33 | },
34 | "devDependencies": {
35 | "concurrently": "^7.2.1"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/examples/spa/bonus1/REST_server/server-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "address": "0.0.0.0",
3 | "port": 3333
4 | }
--------------------------------------------------------------------------------
/examples/spa/bonus1/REST_server/src/common/constants.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 |
3 | };
--------------------------------------------------------------------------------
/examples/spa/bonus1/REST_server/src/common/utils.js:
--------------------------------------------------------------------------------
1 | const getToken = (request) => {
2 |
3 | };
4 |
5 | module.exports = {
6 |
7 | };
--------------------------------------------------------------------------------
/examples/spa/bonus1/REST_server/src/decorators.js:
--------------------------------------------------------------------------------
1 | module.exports = function(fastify){
2 | fastify.decorate('BadRequest', (request, reply, message) => {
3 | reply.code(400).type('application/json').send(message)
4 | });
5 | fastify.decorate('LoginError', (request, reply) => {
6 | reply.code(401).type('application/json').send({message: 'Unauthorized Error'})
7 | });
8 | fastify.decorate('OnlyAdmin', (request, reply) => {
9 | reply.code(403).type('application/json').send('You have no permission to do it')
10 | });
11 | fastify.decorate('notFound', (request, reply) => {
12 | reply.code(404).type('application/json').send('Not Found')
13 | });
14 |
15 | fastify.decorate("getTokenDecoded", function(request, reply) {
16 | try {
17 | const Auth = request.headers["authorization"];
18 | if (Auth) {
19 | const parsed = Auth.split(" ");
20 | const decodedToken = fastify.jwt.decode(parsed[1]);
21 | return decodedToken;
22 | }
23 | } catch (err) {
24 | return null;
25 | }
26 | return null;
27 | })
28 |
29 | };
--------------------------------------------------------------------------------
/examples/spa/bonus1/REST_server/src/handlers/auth/auth.js:
--------------------------------------------------------------------------------
1 | const login = function(fastify) {
2 | return (request, reply) => {
3 | const { login, password } = request.body;
4 |
5 | const token = fastify.jwt.sign({
6 | user_id: '123',
7 | user_login: login,
8 | user_name: 'user name',
9 | randomData: Math.random()
10 | });
11 |
12 | reply.send({ token });
13 | };
14 | };
15 |
16 | module.exports = {
17 | login,
18 | };
19 |
--------------------------------------------------------------------------------
/examples/spa/bonus1/REST_server/src/handlers/auth/index.js:
--------------------------------------------------------------------------------
1 |
2 | const auth = require('./auth');
3 |
4 | module.exports = {
5 | ...auth
6 | };
--------------------------------------------------------------------------------
/examples/spa/bonus1/REST_server/src/handlers/comments/index.js:
--------------------------------------------------------------------------------
1 | const comments = require('./comments');
2 |
3 | module.exports = {
4 | ...comments
5 | };
--------------------------------------------------------------------------------
/examples/spa/bonus1/REST_server/src/handlers/posts/index.js:
--------------------------------------------------------------------------------
1 | const posts = require('./posts');
2 |
3 | module.exports = {
4 | ...posts
5 | };
--------------------------------------------------------------------------------
/examples/spa/bonus1/REST_server/src/handlers/users/index.js:
--------------------------------------------------------------------------------
1 | const users = require('./users');
2 |
3 | module.exports = {
4 | ...users
5 | };
--------------------------------------------------------------------------------
/examples/spa/bonus1/REST_server/src/plugins/awt-plugin.js:
--------------------------------------------------------------------------------
1 | const fp = require("fastify-plugin")
2 |
3 | module.exports = fp(async function(fastify, opts) {
4 | fastify.register(require("@fastify/jwt"), {
5 | secret: "supersecret"
6 | });
7 |
8 | fastify.decorate("authenticate", async function(request, reply, done) {
9 | try {
10 | await request.jwtVerify();
11 | done();
12 | } catch (err) {
13 | reply.send(err);
14 | }
15 | });
16 |
17 | fastify.decorate("isAdmin", async function(request, reply, done) {
18 | try {
19 | const decodedToken = await request.jwtVerify();
20 | if(decodedToken['user_admin']){
21 | done();
22 | } else {
23 | fastify.OnlyAdmin(request, reply);
24 | }
25 | } catch (err) {
26 | reply.send(err);
27 | }
28 | });
29 | })
30 |
--------------------------------------------------------------------------------
/examples/spa/bonus1/REST_server/src/routes/auth-routes.js:
--------------------------------------------------------------------------------
1 | const authHandlers = require("../handlers/auth");
2 |
3 | const addRoutes = fastify => {
4 |
5 | fastify.post(
6 | "/login",
7 | {
8 | schema: {
9 | description: "Log in into the system",
10 | tags: ['auth'],
11 | summary: "Log in into the system",
12 | params: {},
13 | body: {
14 | type: "object",
15 | properties: {
16 | login: {
17 | type: "string",
18 | description: `user's email`
19 | },
20 | password: {
21 | type: "string",
22 | description: "user password"
23 | }
24 | }
25 | },
26 | response: {
27 | 200: {
28 | description: "Successful loggin",
29 | type: "object",
30 | properties: {
31 | token: { type: "string" }
32 | }
33 | }
34 | },
35 | security: []
36 | }
37 | },
38 | authHandlers.login(fastify)
39 | );
40 |
41 |
42 | };
43 |
44 | module.exports = addRoutes;
45 |
--------------------------------------------------------------------------------
/examples/spa/bonus1/REST_server/src/routes/index.js:
--------------------------------------------------------------------------------
1 |
2 | const usersRoutes = require('./users-routes');
3 | const postsRoutes = require('./posts-routes');
4 | const commentsRoutes = require('./comments-routes');
5 | const authRoutes = require('./auth-routes');
6 |
7 | const addAllRoutes = (fastify) => {
8 | fastify.get('/', async (request, reply) => {
9 | return { result: 'ok' }
10 | });
11 | fastify.post('/', async (request, reply) => {
12 | return { result: 'ok' }
13 | });
14 |
15 | usersRoutes(fastify);
16 | postsRoutes(fastify);
17 | commentsRoutes(fastify);
18 | authRoutes(fastify);
19 | };
20 |
21 | module.exports = addAllRoutes;
--------------------------------------------------------------------------------
/examples/spa/bonus1/REST_server/src/routes/schemas/allSchemas.js:
--------------------------------------------------------------------------------
1 | const user = require('./user')
2 | const { postShort, postFull } = require('./post')
3 | const { commentShort, commentFull, commentWithOutPost } = require('./comment')
4 | const { queryPagination } = require('./querystrings')
5 | const pagination = require('./pagination')
6 |
7 | module.exports = (fastify) => {
8 | fastify.addSchema(user)
9 | fastify.addSchema(postShort)
10 | fastify.addSchema(postFull)
11 | fastify.addSchema(commentShort)
12 | fastify.addSchema(commentFull)
13 | fastify.addSchema(commentWithOutPost)
14 | fastify.addSchema(queryPagination)
15 | fastify.addSchema(pagination)
16 |
17 | }
--------------------------------------------------------------------------------
/examples/spa/bonus1/REST_server/src/routes/schemas/comment.js:
--------------------------------------------------------------------------------
1 |
2 | const commentShort = {
3 | $id: "commentShort",
4 | "type": "object",
5 | "properties": {
6 | "id": {
7 | "type": "string",
8 | "format": "uuid",
9 | "description": "post public ID"
10 | },
11 | "text": {
12 | "type": "string",
13 | "description": "post text"
14 | },
15 | "createdAt": {
16 | "type": "string",
17 | "description": "creating date"
18 | },
19 | }
20 | }
21 |
22 | const commentFull = {
23 | $id: "commentFull",
24 | type: "object",
25 | properties: {
26 | ...commentShort.properties,
27 | user: {$ref: 'user#'},
28 | post: {$ref: 'postShort#'},
29 |
30 | }
31 | }
32 |
33 | const commentWithOutPost = {
34 | $id: "commentWithOutPost",
35 | type: "object",
36 | properties: {
37 | ...commentShort.properties,
38 | user: {$ref: 'user#'},
39 | }
40 | }
41 |
42 | module.exports = {commentShort, commentFull, commentWithOutPost};
--------------------------------------------------------------------------------
/examples/spa/bonus1/REST_server/src/routes/schemas/pagination.js:
--------------------------------------------------------------------------------
1 | const schema = {
2 | $id: 'pagination',
3 | "type": "object",
4 | "properties": {
5 | "totalCount": {
6 | "type": "number",
7 | "description": "total count"
8 | },
9 | "limit": {
10 | "type": "number",
11 | "description": "current limit"
12 | },
13 | "page": {
14 | "type": "number",
15 | "description": "current page number"
16 | }
17 | }
18 | }
19 |
20 | module.exports = schema;
--------------------------------------------------------------------------------
/examples/spa/bonus1/REST_server/src/routes/schemas/post.js:
--------------------------------------------------------------------------------
1 | const postShort = {
2 | $id: 'postShort',
3 | "type": "object",
4 | "properties": {
5 | "id": {
6 | "type": "string",
7 | "format": "uuid",
8 | "description": "post public ID"
9 | },
10 | "title": {
11 | "type": "string",
12 | "description": "post title"
13 | },
14 | "text": {
15 | "type": "string",
16 | "description": "post text"
17 | },
18 | "createdAt": {
19 | "type": "string",
20 | "description": "creating date"
21 | },
22 | }
23 | }
24 |
25 | const postFull = {
26 | $id: 'postFull',
27 | "type": "object",
28 | properties: {
29 | ...postShort.properties,
30 | user: {$ref: 'user#'}
31 | }
32 | }
33 |
34 | module.exports = {postShort, postFull};
--------------------------------------------------------------------------------
/examples/spa/bonus1/REST_server/src/routes/schemas/querystrings.js:
--------------------------------------------------------------------------------
1 | const queryPagination = {
2 | $id: 'queryPagination',
3 | type: "object",
4 | properties: {
5 | limit: {
6 | in: 'query',
7 | type: 'number',
8 | description: "max records to return",
9 | },
10 | _page: {
11 | in: 'query',
12 | type: 'number',
13 | description: "page number to return",
14 | },
15 | userId: {
16 | in: 'query',
17 | type: 'string',
18 | format: "uuid",
19 | description: "search by userId",
20 | },
21 | search: {
22 | in: 'query',
23 | type: 'string',
24 | description: "search by sub-string",
25 | }
26 |
27 | },
28 | required: ['limit', '_page']
29 | }
30 |
31 |
32 | module.exports = { queryPagination };
--------------------------------------------------------------------------------
/examples/spa/bonus1/REST_server/src/routes/schemas/user.js:
--------------------------------------------------------------------------------
1 | const user = {
2 | $id: 'user',
3 | "type": "object",
4 | "properties": {
5 | "id": {
6 | "type": "string",
7 | "format": "uuid",
8 | "description": "user's public ID"
9 | },
10 | "user_name": {
11 | "type": "string",
12 | "description": "users's name"
13 | },
14 | "user_fullname": {
15 | "type": "string",
16 | "description": "user's full name"
17 | }
18 | }
19 | }
20 |
21 |
22 | module.exports = user;
--------------------------------------------------------------------------------
/examples/spa/bonus1/generateDB/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "MongoDB",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "license": "MIT",
6 | "dependencies": {
7 | "mongodb": "^4.5.0"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/examples/spa/bonus2/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | SPA on VanillaJs (based on Web Components)
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/examples/spa/bonus2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "spa_example",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "vite",
8 | "build": "cross-env BUILD_TYPE=dev vite build",
9 | "serve": "vite preview --port 3000",
10 | "build-prod": "cross-env BUILD_TYPE=prod vite build",
11 | "test": "echo \"Error: no test specified\" && exit 1"
12 | },
13 | "keywords": [],
14 | "author": "",
15 | "license": "ISC",
16 | "devDependencies": {
17 | "@vitejs/plugin-legacy": "^1.7.0",
18 | "cross-env": "^7.0.3",
19 | "sass": "^1.46.0",
20 | "vite": "^2.8.0",
21 | "vite-aliases": "^0.8.7"
22 | },
23 | "dependencies": {
24 | "route-parser": "0.0.5"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/examples/spa/bonus2/plugins/vite-template-plugin.js:
--------------------------------------------------------------------------------
1 | const fileRegex = /\.(template)$/
2 |
3 | export default function templatePlugin(){
4 | return {
5 | name: 'template-loader-plugin',
6 |
7 | transform(src, id) {
8 | if(fileRegex.test(id)) {
9 | return {
10 | code: `export default function template(props = {}){return \`${src}\`}`,
11 | map: null,
12 | }
13 | }
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/api/authApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const login = (user, password) => {
4 | return baseApi.post(`/login`, {login: user, password})
5 | }
6 |
7 |
8 | export default {
9 | login,
10 | }
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/api/commentsApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const getCommentsByPost = (postId, page) => {
4 | return baseApi.get(`/post/${postId}/comments?_page=${page}&limit=10`)
5 | }
6 |
7 | export const getCommentsByUser = (userId, page) => {
8 | return baseApi.get(`/comments?userId=${userId}&_page=${page}&limit=10`)
9 | }
10 |
11 | export const getCommentsSearch = (search, page) => {
12 | return baseApi.get(`/comments?q=${search}&_page=${page}&limit=10`)
13 | }
14 |
15 | export default {
16 | getCommentsByPost,
17 | getCommentsByUser,
18 | }
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/api/index.js:
--------------------------------------------------------------------------------
1 | export {default as postsApi } from './postsApi'
2 | export {default as usersApi } from './usersApi'
3 | export {default as commentsApi } from './commentsApi'
4 | export {default as authApi } from './authApi'
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/api/postsApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const getPosts = (page) => {
4 | return baseApi.get(`/posts?_page=${page}&limit=10`)
5 | }
6 |
7 | export const getPostsByUser = (userId, page) => {
8 | return baseApi.get(`/posts?userId=${userId}&_page=${page}&limit=10`)
9 | }
10 |
11 | export const getPostById = (postId) => {
12 | return baseApi.get(`/post/${postId}`)
13 | }
14 |
15 | export const getPostsSearch = (search, page) => {
16 | return baseApi.get(`/posts?search=${search}&_page=${page}&limit=10`)
17 | }
18 |
19 | export default {
20 | getPosts,
21 | getPostsByUser,
22 | getPostById,
23 | getPostsSearch,
24 | }
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/api/usersApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const getUsers = (page) => {
4 | return baseApi.get(`/users?_page=${page}&limit=10`)
5 | }
6 |
7 | export const getUserById = (userId) => {
8 | return baseApi.get(`/user/${userId}`)
9 | }
10 |
11 | export const getUsersSearch = (search, page) => {
12 | return baseApi.get(`/users?search=${search}&_page=${page}&limit=10`)
13 | }
14 |
15 | export default {
16 | getUsers,
17 | getUserById,
18 | getUsersSearch,
19 | }
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/common/constants.js:
--------------------------------------------------------------------------------
1 | const appConstants = {
2 | routes: {
3 | index: '/',
4 | posts: '/posts',
5 | postsSearch: '/posts/query/:query',
6 | usersSearch: '/users/query/:query',
7 | users: '/users',
8 | post: '/post/:post',
9 | user: '/user/:user',
10 | userPosts: '/user/:user/posts',
11 | userComments: '/user/:user/comments',
12 | },
13 | search: {
14 | types: {
15 | post: 'post',
16 | user: 'user',
17 | }
18 | },
19 | lists: {
20 | types: {
21 | post: 'post',
22 | user: 'user',
23 | comment: 'comment',
24 | }
25 | },
26 | storage: {
27 | keys: {
28 | token: 'token'
29 | }
30 | },
31 | }
32 |
33 | export default appConstants
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/components/index.js:
--------------------------------------------------------------------------------
1 | import './link-component'
2 | import './nav-component'
3 | import './user-avatar'
4 | import './post-component'
5 | import './user-component'
6 | import './list-component'
7 | import './pagination-component'
8 | import './post-detail'
9 | import './comment-component'
10 | import './date-formatted'
11 | import './app-component'
12 | import './fake-form'
13 | import './modal-dialog'
14 |
15 |
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/index.js:
--------------------------------------------------------------------------------
1 | import './styles/main.scss'
2 | import initRouter from './router'
3 | import './components'
4 |
5 | initRouter()
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/pages/main.template:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 | ${props.topBlock || ''}
10 | ${props.leftBlock || ''}
11 | ${props.rightBlock || ''}
12 | ${props.bottomBlock || ''}
13 |
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/pages/main/bottom.template:
--------------------------------------------------------------------------------
1 |
25 |
26 | ${ [...Array(20).keys()].map((block)=>{
27 | return `
Bottom block ${block+1}
`
28 | }).join('\n')}
29 |
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/pages/main/right.template:
--------------------------------------------------------------------------------
1 |
30 |
31 |
32 | ${ [...Array(12).keys()].map((block)=>{
33 | return `
34 |
35 |
`
36 | }).join('\n')}
37 |
38 |
39 |
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/pages/main/top.template:
--------------------------------------------------------------------------------
1 |
23 |
24 | ${ [...Array(10).keys()].map((block)=>{
25 | return `
Top block ${block+1}
`
26 | }).join('\n')}
27 |
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/pages/post.template:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/pages/posts.template:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/pages/user.template:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/pages/userComments.template:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/pages/userPosts.template:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/pages/users.template:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/service/comments.js:
--------------------------------------------------------------------------------
1 | const comments = new Map()
2 |
3 | export const getComment = (commentId) => {
4 | return comments.get(commentId)
5 | }
6 |
7 | export const setComment = (comment) => {
8 | return comments.set(comment.id, comment)
9 | }
10 |
11 | export default {
12 | getComment,
13 | setComment,
14 | }
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/service/posts.js:
--------------------------------------------------------------------------------
1 | const posts = new Map()
2 |
3 | export const getPost = (postId) => {
4 | return posts.get(postId)
5 | }
6 |
7 | export const setPost = (post) => {
8 | posts.set(post.id, post)
9 | }
10 |
11 | export default {
12 | getPost,
13 | setPost
14 | }
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/service/users.js:
--------------------------------------------------------------------------------
1 | const users = new Map()
2 |
3 | export const getUser = (userId) => {
4 | return users.get(userId)
5 | }
6 |
7 | export const setUser = (user) => {
8 | users.set(user.id, user)
9 | }
10 |
11 | export default {
12 | getUser,
13 | setUser
14 | }
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/styles/common.scss:
--------------------------------------------------------------------------------
1 |
2 | body{
3 | background-color: #fff;
4 | color: #000;
5 | }
6 |
--------------------------------------------------------------------------------
/examples/spa/bonus2/src/styles/main.scss:
--------------------------------------------------------------------------------
1 | @import 'common.scss';
2 |
3 | body{
4 | background-color: #fff;
5 | color: #000;
6 | }
7 |
--------------------------------------------------------------------------------
/examples/spa/bonus2/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import { ViteAliases } from "vite-aliases";
3 | import legacy from "@vitejs/plugin-legacy"
4 | import TemplateLoader from './plugins/vite-template-plugin'
5 |
6 | export default defineConfig({
7 | build: {
8 | target: 'es2017',
9 | outDir: 'build',
10 | },
11 | server: {
12 | port: 3000,
13 | host: '0.0.0.0',
14 | hmr: true,
15 | },
16 | plugins: [
17 | ViteAliases(),
18 | TemplateLoader(),
19 | legacy({
20 | targets: ['defaults', 'not IE 11'],
21 | })
22 | ],
23 | })
--------------------------------------------------------------------------------
/examples/spa/part1/README.md:
--------------------------------------------------------------------------------
1 | # SPA приложение на основе web компонентов (часть 1).
2 |
3 | ## Как пользоваться
4 |
5 | npm install
6 |
7 | #### Запуск приложения
8 |
9 | npm run start
10 |
11 |
12 | ## Команды для сборки дев и прод версий
13 |
14 | npm run build
15 | npm run ibuild-prod
16 |
17 | ## Видео с объяснением как это все работает здесь:
18 |
19 | https://youtu.be/eqAefmCqA6M
20 |
21 |
22 | ## Другие видео по Vanilla js:
23 |
24 | - Эффект падающего снега для сайта https://youtu.be/3xk4ldXe4YI
25 | - Введиние в Cordova, часть 1 https://youtu.be/O5mQRVTmUf4
26 | - Введиние в Cordova, часть 2 https://youtu.be/-R3fA4cVWFM
27 | - Введиние в Cordova, часть 3 https://youtu.be/hMtQKROmHZs
28 | - Введиние в Cordova, часть 4 https://youtu.be/SUUmj8YgbQY
29 |
30 |
31 | ## Полезные видео по настройке webpack:
32 |
33 | - Настройка горячей перезагрузки - https://youtu.be/oOpzkF2nU0s
34 |
35 | - Настройка сборки проекта с подгрузкой файлов css/scss/изображений - https://youtu.be/3B-NGZmMe-Y
36 |
37 | - Модульный принцип конфигурации проекта - https://youtu.be/fnUqyWyG5kk
38 |
39 |
--------------------------------------------------------------------------------
/examples/spa/part1/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SPA on VanillaJs (based on Web Components)
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/spa/part1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "spa_example",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "vite",
8 | "build": "cross-env BUILD_TYPE=dev vite build",
9 | "serve": "vite preview --port 3000",
10 | "build-prod": "cross-env BUILD_TYPE=prod vite build",
11 | "test": "echo \"Error: no test specified\" && exit 1"
12 | },
13 | "keywords": [],
14 | "author": "",
15 | "license": "ISC",
16 | "devDependencies": {
17 | "@vitejs/plugin-legacy": "^1.7.0",
18 | "cross-env": "^7.0.3",
19 | "sass": "^1.46.0",
20 | "vite": "^2.8.0",
21 | "vite-aliases": "^0.8.7"
22 | },
23 | "dependencies": {
24 | "route-parser": "0.0.5"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/examples/spa/part1/plugins/vite-template-plugin.js:
--------------------------------------------------------------------------------
1 | const fileRegex = /\.(template)$/
2 |
3 | export default function templatePlugin(){
4 | return {
5 | name: 'template-loader-plugin',
6 |
7 | transform(src, id) {
8 | if(fileRegex.test(id)) {
9 | return {
10 | code: `export default function template(props = {}){return \`${src}\`}`,
11 | map: null,
12 | }
13 | }
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/examples/spa/part1/src/common/constants.js:
--------------------------------------------------------------------------------
1 | const appConstants = {
2 | routes: {
3 | index: '/',
4 | posts: '/posts',
5 | users: '/users',
6 | },
7 | search: {
8 | types: {
9 | post: 'post',
10 | user: 'user'
11 | }
12 | }
13 | }
14 |
15 | export default appConstants
--------------------------------------------------------------------------------
/examples/spa/part1/src/index.js:
--------------------------------------------------------------------------------
1 | import './styles/main.scss'
2 | import initRouter from './router'
3 |
4 | initRouter()
5 |
6 |
7 |
--------------------------------------------------------------------------------
/examples/spa/part1/src/pages/main.template:
--------------------------------------------------------------------------------
1 | Main template (new content)
--------------------------------------------------------------------------------
/examples/spa/part1/src/pages/posts.template:
--------------------------------------------------------------------------------
1 | Posts template
--------------------------------------------------------------------------------
/examples/spa/part1/src/pages/users.template:
--------------------------------------------------------------------------------
1 | Users template
--------------------------------------------------------------------------------
/examples/spa/part1/src/styles/common.scss:
--------------------------------------------------------------------------------
1 |
2 | body{
3 | background-color: #fff;
4 | color: #000;
5 | }
6 |
--------------------------------------------------------------------------------
/examples/spa/part1/src/styles/main.scss:
--------------------------------------------------------------------------------
1 | @import 'common.scss';
2 |
3 | body{
4 | background-color: #fff;
5 | color: #000;
6 | }
7 |
--------------------------------------------------------------------------------
/examples/spa/part1/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import { ViteAliases } from "vite-aliases";
3 | import legacy from "@vitejs/plugin-legacy"
4 | import TemplateLoader from './plugins/vite-template-plugin'
5 |
6 | export default defineConfig({
7 | build: {
8 | target: 'es2017',
9 | outDir: 'build',
10 | },
11 | server: {
12 | port: 3000,
13 | host: '0.0.0.0',
14 | hmr: true,
15 | },
16 | plugins: [
17 | ViteAliases(),
18 | TemplateLoader(),
19 | legacy({
20 | targets: ['defaults', 'not IE 11'],
21 | })
22 | ],
23 | })
--------------------------------------------------------------------------------
/examples/spa/part2/README.md:
--------------------------------------------------------------------------------
1 | # SPA приложение на основе web компонентов (часть 2).
2 |
3 | ## Как пользоваться
4 |
5 | npm install
6 |
7 | #### Запуск приложения
8 |
9 | npm run start
10 |
11 |
12 | ## Команды для сборки дев и прод версий
13 |
14 | npm run build
15 | npm run build-prod
16 |
17 | ## Видео с объяснением как это все работает здесь:
18 |
19 | https://youtu.be/HKFEUBXuAxc
20 |
21 | ## Видео первой части здесь:
22 |
23 | https://youtu.be/eqAefmCqA6M
24 |
25 |
26 | ## Другие видео по Vanilla js:
27 |
28 | - Эффект падающего снега для сайта https://youtu.be/3xk4ldXe4YI
29 | - Введиние в Cordova, часть 1 https://youtu.be/O5mQRVTmUf4
30 | - Введиние в Cordova, часть 2 https://youtu.be/-R3fA4cVWFM
31 | - Введиние в Cordova, часть 3 https://youtu.be/hMtQKROmHZs
32 | - Введиние в Cordova, часть 4 https://youtu.be/SUUmj8YgbQY
33 |
34 |
35 | ## Полезные видео по настройке webpack:
36 |
37 | - Настройка горячей перезагрузки - https://youtu.be/oOpzkF2nU0s
38 |
39 | - Настройка сборки проекта с подгрузкой файлов css/scss/изображений - https://youtu.be/3B-NGZmMe-Y
40 |
41 | - Модульный принцип конфигурации проекта - https://youtu.be/fnUqyWyG5kk
42 |
43 |
--------------------------------------------------------------------------------
/examples/spa/part2/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SPA on VanillaJs (based on Web Components)
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/spa/part2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "spa_example",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "vite",
8 | "build": "cross-env BUILD_TYPE=dev vite build",
9 | "serve": "vite preview --port 3000",
10 | "build-prod": "cross-env BUILD_TYPE=prod vite build",
11 | "test": "echo \"Error: no test specified\" && exit 1"
12 | },
13 | "keywords": [],
14 | "author": "",
15 | "license": "ISC",
16 | "devDependencies": {
17 | "@vitejs/plugin-legacy": "^1.7.0",
18 | "cross-env": "^7.0.3",
19 | "sass": "^1.46.0",
20 | "vite": "^2.8.0",
21 | "vite-aliases": "^0.8.7"
22 | },
23 | "dependencies": {
24 | "route-parser": "0.0.5"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/examples/spa/part2/plugins/vite-template-plugin.js:
--------------------------------------------------------------------------------
1 | const fileRegex = /\.(template)$/
2 |
3 | export default function templatePlugin(){
4 | return {
5 | name: 'template-loader-plugin',
6 |
7 | transform(src, id) {
8 | if(fileRegex.test(id)) {
9 | return {
10 | code: `export default function template(props = {}){return \`${src}\`}`,
11 | map: null,
12 | }
13 | }
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/examples/spa/part2/src/common/constants.js:
--------------------------------------------------------------------------------
1 | const appConstants = {
2 | routes: {
3 | index: '/',
4 | posts: '/posts',
5 | users: '/users',
6 | },
7 | search: {
8 | types: {
9 | post: 'post',
10 | user: 'user'
11 | }
12 | }
13 | }
14 |
15 | export default appConstants
--------------------------------------------------------------------------------
/examples/spa/part2/src/components/index.js:
--------------------------------------------------------------------------------
1 | import './link-component'
2 | import './nav-component'
3 |
--------------------------------------------------------------------------------
/examples/spa/part2/src/index.js:
--------------------------------------------------------------------------------
1 | import './styles/main.scss'
2 | import initRouter from './router'
3 | import './components'
4 |
5 | initRouter()
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/spa/part2/src/pages/main.template:
--------------------------------------------------------------------------------
1 |
2 | Main template (new content)
--------------------------------------------------------------------------------
/examples/spa/part2/src/pages/posts.template:
--------------------------------------------------------------------------------
1 |
2 | Posts template
--------------------------------------------------------------------------------
/examples/spa/part2/src/pages/users.template:
--------------------------------------------------------------------------------
1 |
2 | Users template
--------------------------------------------------------------------------------
/examples/spa/part2/src/styles/common.scss:
--------------------------------------------------------------------------------
1 |
2 | body{
3 | background-color: #fff;
4 | color: #000;
5 | }
6 |
--------------------------------------------------------------------------------
/examples/spa/part2/src/styles/main.scss:
--------------------------------------------------------------------------------
1 | @import 'common.scss';
2 |
3 | body{
4 | background-color: #fff;
5 | color: #000;
6 | }
7 |
--------------------------------------------------------------------------------
/examples/spa/part2/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import { ViteAliases } from "vite-aliases";
3 | import legacy from "@vitejs/plugin-legacy"
4 | import TemplateLoader from './plugins/vite-template-plugin'
5 |
6 | export default defineConfig({
7 | build: {
8 | target: 'es2017',
9 | outDir: 'build',
10 | },
11 | server: {
12 | port: 3000,
13 | host: '0.0.0.0',
14 | hmr: true,
15 | },
16 | plugins: [
17 | ViteAliases(),
18 | TemplateLoader(),
19 | legacy({
20 | targets: ['defaults', 'not IE 11'],
21 | })
22 | ],
23 | })
--------------------------------------------------------------------------------
/examples/spa/part3/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SPA on VanillaJs (based on Web Components)
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/spa/part3/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "spa_example",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "vite",
8 | "build": "cross-env BUILD_TYPE=dev vite build",
9 | "serve": "vite preview --port 3000",
10 | "build-prod": "cross-env BUILD_TYPE=prod vite build",
11 | "server": "json-server --port 1111 ./db.json",
12 | "test": "echo \"Error: no test specified\" && exit 1"
13 | },
14 | "keywords": [],
15 | "author": "",
16 | "license": "ISC",
17 | "devDependencies": {
18 | "@vitejs/plugin-legacy": "^1.7.0",
19 | "cross-env": "^7.0.3",
20 | "sass": "^1.46.0",
21 | "vite": "^2.8.0",
22 | "vite-aliases": "^0.8.7"
23 | },
24 | "dependencies": {
25 | "route-parser": "0.0.5"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/examples/spa/part3/plugins/vite-template-plugin.js:
--------------------------------------------------------------------------------
1 | const fileRegex = /\.(template)$/
2 |
3 | export default function templatePlugin(){
4 | return {
5 | name: 'template-loader-plugin',
6 |
7 | transform(src, id) {
8 | if(fileRegex.test(id)) {
9 | return {
10 | code: `export default function template(props = {}){return \`${src}\`}`,
11 | map: null,
12 | }
13 | }
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/examples/spa/part3/src/api/commentsApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const getCommentsByPosts = (postId, page) => {
4 | return baseApi.get(`/posts/${postId}/comments?_page=${page}&limit=10&_expand=user&_sort=createAt`)
5 | }
6 |
7 | export const getCommentsByUser = (userId, page) => {
8 | return baseApi.get(`/comments?userId=${userId}&_page=${page}&_expand=user&_expand=post`)
9 | }
10 |
11 | export default {
12 | getCommentsByPosts,
13 | getCommentsByUser,
14 | }
--------------------------------------------------------------------------------
/examples/spa/part3/src/api/index.js:
--------------------------------------------------------------------------------
1 | export {default as postsApi } from './postsApi'
2 | export {default as usersApi } from './usersApi'
3 | export {default as commentsApi } from './commentsApi'
--------------------------------------------------------------------------------
/examples/spa/part3/src/api/postsApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const getPosts = (page) => {
4 | return baseApi.get(`/posts?_page=${page}&limit=10&_expand=user`)
5 | }
6 |
7 | export const getPostsByUser = (userId, page) => {
8 | return baseApi.get(`/posts?userId=${userId}&_page=${page}&limit=10&_expand=user`)
9 | }
10 |
11 | export const getPostsById = (postId) => {
12 | return baseApi.get(`/posts/postId=${postId}?_expand=user`)
13 | }
14 |
15 | export const getPostsSearch = (search, page) => {
16 | return baseApi.get(`/posts?q=${search}&_page=${page}&limit=10&_expand=user`)
17 | }
18 |
19 | export default {
20 | getPosts,
21 | getPostsByUser,
22 | getPostsById,
23 | getPostsSearch,
24 | }
--------------------------------------------------------------------------------
/examples/spa/part3/src/api/usersApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const getUsers = (page) => {
4 | return baseApi.get(`/users?_page=${page}&limit=10`)
5 | }
6 |
7 | export const getUsersById = (userId) => {
8 | return baseApi.get(`/users/userId=${userId}`)
9 | }
10 |
11 | export const getUsersSearch = (search, page) => {
12 | return baseApi.get(`/users?q=${search}&_page=${page}&limit=10`)
13 | }
14 |
15 | export default {
16 | getUsers,
17 | getUsersById,
18 | getUsersSearch,
19 | }
--------------------------------------------------------------------------------
/examples/spa/part3/src/common/constants.js:
--------------------------------------------------------------------------------
1 | const appConstants = {
2 | routes: {
3 | index: '/',
4 | posts: '/posts',
5 | users: '/users',
6 | },
7 | search: {
8 | types: {
9 | post: 'post',
10 | user: 'user'
11 | }
12 | }
13 | }
14 |
15 | export default appConstants
--------------------------------------------------------------------------------
/examples/spa/part3/src/components/index.js:
--------------------------------------------------------------------------------
1 | import './link-component'
2 | import './nav-component'
3 |
--------------------------------------------------------------------------------
/examples/spa/part3/src/index.js:
--------------------------------------------------------------------------------
1 | import './styles/main.scss'
2 | import initRouter from './router'
3 | import './components'
4 |
5 | initRouter()
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/spa/part3/src/pages/main.template:
--------------------------------------------------------------------------------
1 |
2 | Main template (new content)
--------------------------------------------------------------------------------
/examples/spa/part3/src/pages/posts.template:
--------------------------------------------------------------------------------
1 |
2 | Posts template
--------------------------------------------------------------------------------
/examples/spa/part3/src/pages/users.template:
--------------------------------------------------------------------------------
1 |
2 | Users template
--------------------------------------------------------------------------------
/examples/spa/part3/src/styles/common.scss:
--------------------------------------------------------------------------------
1 |
2 | body{
3 | background-color: #fff;
4 | color: #000;
5 | }
6 |
--------------------------------------------------------------------------------
/examples/spa/part3/src/styles/main.scss:
--------------------------------------------------------------------------------
1 | @import 'common.scss';
2 |
3 | body{
4 | background-color: #fff;
5 | color: #000;
6 | }
7 |
--------------------------------------------------------------------------------
/examples/spa/part3/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import { ViteAliases } from "vite-aliases";
3 | import legacy from "@vitejs/plugin-legacy"
4 | import TemplateLoader from './plugins/vite-template-plugin'
5 |
6 | export default defineConfig({
7 | build: {
8 | target: 'es2017',
9 | outDir: 'build',
10 | },
11 | server: {
12 | port: 3000,
13 | host: '0.0.0.0',
14 | hmr: true,
15 | },
16 | plugins: [
17 | ViteAliases(),
18 | TemplateLoader(),
19 | legacy({
20 | targets: ['defaults', 'not IE 11'],
21 | })
22 | ],
23 | })
--------------------------------------------------------------------------------
/examples/spa/part4/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SPA on VanillaJs (based on Web Components)
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/spa/part4/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "spa_example",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "vite",
8 | "build": "cross-env BUILD_TYPE=dev vite build",
9 | "serve": "vite preview --port 3000",
10 | "build-prod": "cross-env BUILD_TYPE=prod vite build",
11 | "server": "json-server --port 1111 ./db.json",
12 | "test": "echo \"Error: no test specified\" && exit 1"
13 | },
14 | "keywords": [],
15 | "author": "",
16 | "license": "ISC",
17 | "devDependencies": {
18 | "@vitejs/plugin-legacy": "^1.7.0",
19 | "cross-env": "^7.0.3",
20 | "sass": "^1.46.0",
21 | "vite": "^2.8.0",
22 | "vite-aliases": "^0.8.7"
23 | },
24 | "dependencies": {
25 | "route-parser": "0.0.5"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/examples/spa/part4/plugins/vite-template-plugin.js:
--------------------------------------------------------------------------------
1 | const fileRegex = /\.(template)$/
2 |
3 | export default function templatePlugin(){
4 | return {
5 | name: 'template-loader-plugin',
6 |
7 | transform(src, id) {
8 | if(fileRegex.test(id)) {
9 | return {
10 | code: `export default function template(props = {}){return \`${src}\`}`,
11 | map: null,
12 | }
13 | }
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/examples/spa/part4/src/api/commentsApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const getCommentsByPosts = (postId, page) => {
4 | return baseApi.get(`/posts/${postId}/comments?_page=${page}&limit=10&_expand=user&_sort=createAt`)
5 | }
6 |
7 | export const getCommentsByUser = (userId, page) => {
8 | return baseApi.get(`/comments?userId=${userId}&_page=${page}&_expand=user&_expand=post`)
9 | }
10 |
11 | export default {
12 | getCommentsByPosts,
13 | getCommentsByUser,
14 | }
--------------------------------------------------------------------------------
/examples/spa/part4/src/api/index.js:
--------------------------------------------------------------------------------
1 | export {default as postsApi } from './postsApi'
2 | export {default as usersApi } from './usersApi'
3 | export {default as commentsApi } from './commentsApi'
--------------------------------------------------------------------------------
/examples/spa/part4/src/api/postsApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const getPosts = (page) => {
4 | return baseApi.get(`/posts?_page=${page}&limit=10&_expand=user`)
5 | }
6 |
7 | export const getPostsByUser = (userId, page) => {
8 | return baseApi.get(`/posts?userId=${userId}&_page=${page}&limit=10&_expand=user`)
9 | }
10 |
11 | export const getPostsById = (postId) => {
12 | return baseApi.get(`/posts/postId=${postId}?_expand=user`)
13 | }
14 |
15 | export const getPostsSearch = (search, page) => {
16 | return baseApi.get(`/posts?q=${search}&_page=${page}&limit=10&_expand=user`)
17 | }
18 |
19 | export default {
20 | getPosts,
21 | getPostsByUser,
22 | getPostsById,
23 | getPostsSearch,
24 | }
--------------------------------------------------------------------------------
/examples/spa/part4/src/api/usersApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const getUsers = (page) => {
4 | return baseApi.get(`/users?_page=${page}&limit=10`)
5 | }
6 |
7 | export const getUsersById = (userId) => {
8 | return baseApi.get(`/users/userId=${userId}`)
9 | }
10 |
11 | export const getUsersSearch = (search, page) => {
12 | return baseApi.get(`/users?q=${search}&_page=${page}&limit=10`)
13 | }
14 |
15 | export default {
16 | getUsers,
17 | getUsersById,
18 | getUsersSearch,
19 | }
--------------------------------------------------------------------------------
/examples/spa/part4/src/common/constants.js:
--------------------------------------------------------------------------------
1 | const appConstants = {
2 | routes: {
3 | index: '/',
4 | posts: '/posts',
5 | users: '/users',
6 | },
7 | search: {
8 | types: {
9 | post: 'post',
10 | user: 'user'
11 | }
12 | }
13 | }
14 |
15 | export default appConstants
--------------------------------------------------------------------------------
/examples/spa/part4/src/components/index.js:
--------------------------------------------------------------------------------
1 | import './link-component'
2 | import './nav-component'
3 | import './user-avatar'
4 | import './post-component'
5 | import './posts-component'
6 | import './pagination-component'
7 |
8 |
--------------------------------------------------------------------------------
/examples/spa/part4/src/index.js:
--------------------------------------------------------------------------------
1 | import './styles/main.scss'
2 | import initRouter from './router'
3 | import './components'
4 |
5 | initRouter()
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/spa/part4/src/pages/main.template:
--------------------------------------------------------------------------------
1 |
2 | Main template (new content)
--------------------------------------------------------------------------------
/examples/spa/part4/src/pages/posts.template:
--------------------------------------------------------------------------------
1 |
2 | Posts template
--------------------------------------------------------------------------------
/examples/spa/part4/src/pages/users.template:
--------------------------------------------------------------------------------
1 |
2 | Users template
--------------------------------------------------------------------------------
/examples/spa/part4/src/service/posts.js:
--------------------------------------------------------------------------------
1 | const posts = new Map()
2 |
3 | export const getPost = (postId) => {
4 | return posts.get(postId)
5 | }
6 |
7 | export const setPost = (post) => {
8 | posts.set(post.id, post)
9 | }
10 |
11 | export default {
12 | getPost,
13 | setPost
14 | }
--------------------------------------------------------------------------------
/examples/spa/part4/src/styles/common.scss:
--------------------------------------------------------------------------------
1 |
2 | body{
3 | background-color: #fff;
4 | color: #000;
5 | }
6 |
--------------------------------------------------------------------------------
/examples/spa/part4/src/styles/main.scss:
--------------------------------------------------------------------------------
1 | @import 'common.scss';
2 |
3 | body{
4 | background-color: #fff;
5 | color: #000;
6 | }
7 |
--------------------------------------------------------------------------------
/examples/spa/part4/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import { ViteAliases } from "vite-aliases";
3 | import legacy from "@vitejs/plugin-legacy"
4 | import TemplateLoader from './plugins/vite-template-plugin'
5 |
6 | export default defineConfig({
7 | build: {
8 | target: 'es2017',
9 | outDir: 'build',
10 | },
11 | server: {
12 | port: 3000,
13 | host: '0.0.0.0',
14 | hmr: true,
15 | },
16 | plugins: [
17 | ViteAliases(),
18 | TemplateLoader(),
19 | legacy({
20 | targets: ['defaults', 'not IE 11'],
21 | })
22 | ],
23 | })
--------------------------------------------------------------------------------
/examples/spa/part5/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SPA on VanillaJs (based on Web Components)
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/spa/part5/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "spa_example",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "vite",
8 | "build": "cross-env BUILD_TYPE=dev vite build",
9 | "serve": "vite preview --port 3000",
10 | "build-prod": "cross-env BUILD_TYPE=prod vite build",
11 | "server": "json-server --port 1111 ./db.json",
12 | "test": "echo \"Error: no test specified\" && exit 1"
13 | },
14 | "keywords": [],
15 | "author": "",
16 | "license": "ISC",
17 | "devDependencies": {
18 | "@vitejs/plugin-legacy": "^1.7.0",
19 | "cross-env": "^7.0.3",
20 | "sass": "^1.46.0",
21 | "vite": "^2.8.0",
22 | "vite-aliases": "^0.8.7"
23 | },
24 | "dependencies": {
25 | "route-parser": "0.0.5"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/examples/spa/part5/plugins/vite-template-plugin.js:
--------------------------------------------------------------------------------
1 | const fileRegex = /\.(template)$/
2 |
3 | export default function templatePlugin(){
4 | return {
5 | name: 'template-loader-plugin',
6 |
7 | transform(src, id) {
8 | if(fileRegex.test(id)) {
9 | return {
10 | code: `export default function template(props = {}){return \`${src}\`}`,
11 | map: null,
12 | }
13 | }
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/examples/spa/part5/src/api/commentsApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const getCommentsByPosts = (postId, page) => {
4 | return baseApi.get(`/posts/${postId}/comments?_page=${page}&limit=10&_expand=user&_sort=createAt`)
5 | }
6 |
7 | export const getCommentsByUser = (userId, page) => {
8 | return baseApi.get(`/comments?userId=${userId}&_page=${page}&_expand=user&_expand=post`)
9 | }
10 |
11 | export default {
12 | getCommentsByPosts,
13 | getCommentsByUser,
14 | }
--------------------------------------------------------------------------------
/examples/spa/part5/src/api/index.js:
--------------------------------------------------------------------------------
1 | export {default as postsApi } from './postsApi'
2 | export {default as usersApi } from './usersApi'
3 | export {default as commentsApi } from './commentsApi'
--------------------------------------------------------------------------------
/examples/spa/part5/src/api/postsApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const getPosts = (page) => {
4 | return baseApi.get(`/posts?_page=${page}&limit=10&_expand=user`)
5 | }
6 |
7 | export const getPostsByUser = (userId, page) => {
8 | return baseApi.get(`/posts?userId=${userId}&_page=${page}&limit=10&_expand=user`)
9 | }
10 |
11 | export const getPostsById = (postId) => {
12 | return baseApi.get(`/posts/postId=${postId}?_expand=user`)
13 | }
14 |
15 | export const getPostsSearch = (search, page) => {
16 | return baseApi.get(`/posts?q=${search}&_page=${page}&limit=10&_expand=user`)
17 | }
18 |
19 | export default {
20 | getPosts,
21 | getPostsByUser,
22 | getPostsById,
23 | getPostsSearch,
24 | }
--------------------------------------------------------------------------------
/examples/spa/part5/src/api/usersApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const getUsers = (page) => {
4 | return baseApi.get(`/users?_page=${page}&limit=10`)
5 | }
6 |
7 | export const getUsersById = (userId) => {
8 | return baseApi.get(`/users/userId=${userId}`)
9 | }
10 |
11 | export const getUsersSearch = (search, page) => {
12 | return baseApi.get(`/users?q=${search}&_page=${page}&limit=10`)
13 | }
14 |
15 | export default {
16 | getUsers,
17 | getUsersById,
18 | getUsersSearch,
19 | }
--------------------------------------------------------------------------------
/examples/spa/part5/src/common/constants.js:
--------------------------------------------------------------------------------
1 | const appConstants = {
2 | routes: {
3 | index: '/',
4 | posts: '/posts',
5 | postsSearch: '/posts/query/:query',
6 | users: '/users',
7 | },
8 | search: {
9 | types: {
10 | post: 'post',
11 | user: 'user'
12 | }
13 | }
14 | }
15 |
16 | export default appConstants
--------------------------------------------------------------------------------
/examples/spa/part5/src/components/index.js:
--------------------------------------------------------------------------------
1 | import './link-component'
2 | import './nav-component'
3 | import './user-avatar'
4 | import './post-component'
5 | import './posts-component'
6 | import './pagination-component'
7 |
8 |
--------------------------------------------------------------------------------
/examples/spa/part5/src/index.js:
--------------------------------------------------------------------------------
1 | import './styles/main.scss'
2 | import initRouter from './router'
3 | import './components'
4 |
5 | initRouter()
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/spa/part5/src/pages/main.template:
--------------------------------------------------------------------------------
1 |
2 | Main template (new content)
--------------------------------------------------------------------------------
/examples/spa/part5/src/pages/posts.template:
--------------------------------------------------------------------------------
1 |
2 | Posts template
--------------------------------------------------------------------------------
/examples/spa/part5/src/pages/users.template:
--------------------------------------------------------------------------------
1 |
2 | Users template
--------------------------------------------------------------------------------
/examples/spa/part5/src/service/posts.js:
--------------------------------------------------------------------------------
1 | const posts = new Map()
2 |
3 | export const getPost = (postId) => {
4 | return posts.get(postId)
5 | }
6 |
7 | export const setPost = (post) => {
8 | posts.set(post.id, post)
9 | }
10 |
11 | export default {
12 | getPost,
13 | setPost
14 | }
--------------------------------------------------------------------------------
/examples/spa/part5/src/styles/common.scss:
--------------------------------------------------------------------------------
1 |
2 | body{
3 | background-color: #fff;
4 | color: #000;
5 | }
6 |
--------------------------------------------------------------------------------
/examples/spa/part5/src/styles/main.scss:
--------------------------------------------------------------------------------
1 | @import 'common.scss';
2 |
3 | body{
4 | background-color: #fff;
5 | color: #000;
6 | }
7 |
--------------------------------------------------------------------------------
/examples/spa/part5/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import { ViteAliases } from "vite-aliases";
3 | import legacy from "@vitejs/plugin-legacy"
4 | import TemplateLoader from './plugins/vite-template-plugin'
5 |
6 | export default defineConfig({
7 | build: {
8 | target: 'es2017',
9 | outDir: 'build',
10 | },
11 | server: {
12 | port: 3000,
13 | host: '0.0.0.0',
14 | hmr: true,
15 | },
16 | plugins: [
17 | ViteAliases(),
18 | TemplateLoader(),
19 | legacy({
20 | targets: ['defaults', 'not IE 11'],
21 | })
22 | ],
23 | })
--------------------------------------------------------------------------------
/examples/spa/part6/README.md:
--------------------------------------------------------------------------------
1 | # SPA прилоежние на основе web компонентов.
2 |
3 | ## Как пользоваться
4 |
5 | npm install
6 | npm install -g json-server
7 | npm install -g http-server-spa
8 |
9 | #### Запуск локального REST API сервера
10 |
11 | npm run server
12 |
13 | #### Запуск приложения
14 |
15 | npm run start
16 |
17 |
18 | ## Команды для сборки дев и прод версий
19 |
20 | npm run build
21 | npm run ibuild-prod
22 |
23 | ## Build and run spa server
24 |
25 | npm run build // или npm run build-prod
26 | cd build
27 | http-server-spa . ./index.html 3000
28 |
29 | ## Видео с объяснением как это все работает здесь:
30 |
31 | https://youtu.be/6rA2Wmt9trI
32 |
33 |
34 | ## Другие видео по Vanilla js:
35 |
36 | - Введиние в Cordova, превращаем существующее приложение в мобильное https://youtu.be/O5mQRVTmUf4
37 |
38 | ## Полезные видео по настройке webpack:
39 |
40 | - Настройка горячей перезагрузки - https://youtu.be/oOpzkF2nU0s
41 |
42 | - Настройка сборки проекта с подгрузкой файлов css/scss/изображений - https://youtu.be/3B-NGZmMe-Y
43 |
44 | - Модульный принцип конфигурации проекта - https://youtu.be/fnUqyWyG5kk
45 |
46 |
--------------------------------------------------------------------------------
/examples/spa/part6/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SPA on VanillaJs (based on Web Components)
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/spa/part6/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "spa_example",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "vite",
8 | "build": "cross-env BUILD_TYPE=dev vite build",
9 | "serve": "vite preview --port 3000",
10 | "build-prod": "cross-env BUILD_TYPE=prod vite build",
11 | "server": "json-server --port 1111 ./db.json",
12 | "test": "echo \"Error: no test specified\" && exit 1"
13 | },
14 | "keywords": [],
15 | "author": "",
16 | "license": "ISC",
17 | "devDependencies": {
18 | "@vitejs/plugin-legacy": "^1.7.0",
19 | "cross-env": "^7.0.3",
20 | "sass": "^1.46.0",
21 | "vite": "^2.8.0",
22 | "vite-aliases": "^0.8.7"
23 | },
24 | "dependencies": {
25 | "route-parser": "0.0.5"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/examples/spa/part6/plugins/vite-template-plugin.js:
--------------------------------------------------------------------------------
1 | const fileRegex = /\.(template)$/
2 |
3 | export default function templatePlugin(){
4 | return {
5 | name: 'template-loader-plugin',
6 |
7 | transform(src, id) {
8 | if(fileRegex.test(id)) {
9 | return {
10 | code: `export default function template(props = {}){return \`${src}\`}`,
11 | map: null,
12 | }
13 | }
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/examples/spa/part6/src/api/commentsApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const getCommentsByPosts = (postId, page) => {
4 | return baseApi.get(`/posts/${postId}/comments?_page=${page}&limit=10&_expand=user&_sort=createAt`)
5 | }
6 |
7 | export const getCommentsByUser = (userId, page) => {
8 | return baseApi.get(`/comments?userId=${userId}&_page=${page}&_expand=user&_expand=post`)
9 | }
10 |
11 | export default {
12 | getCommentsByPosts,
13 | getCommentsByUser,
14 | }
--------------------------------------------------------------------------------
/examples/spa/part6/src/api/index.js:
--------------------------------------------------------------------------------
1 | export {default as postsApi } from './postsApi'
2 | export {default as usersApi } from './usersApi'
3 | export {default as commentsApi } from './commentsApi'
--------------------------------------------------------------------------------
/examples/spa/part6/src/api/postsApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const getPosts = (page) => {
4 | return baseApi.get(`/posts?_page=${page}&limit=10&_expand=user`)
5 | }
6 |
7 | export const getPostsByUser = (userId, page) => {
8 | return baseApi.get(`/posts?userId=${userId}&_page=${page}&limit=10&_expand=user`)
9 | }
10 |
11 | export const getPostsById = (postId) => {
12 | return baseApi.get(`/posts/postId=${postId}?_expand=user`)
13 | }
14 |
15 | export const getPostsSearch = (search, page) => {
16 | return baseApi.get(`/posts?q=${search}&_page=${page}&limit=10&_expand=user`)
17 | }
18 |
19 | export default {
20 | getPosts,
21 | getPostsByUser,
22 | getPostsById,
23 | getPostsSearch,
24 | }
--------------------------------------------------------------------------------
/examples/spa/part6/src/api/usersApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const getUsers = (page) => {
4 | return baseApi.get(`/users?_page=${page}&limit=10`)
5 | }
6 |
7 | export const getUsersById = (userId) => {
8 | return baseApi.get(`/users/userId=${userId}`)
9 | }
10 |
11 | export const getUsersSearch = (search, page) => {
12 | return baseApi.get(`/users?q=${search}&_page=${page}&limit=10`)
13 | }
14 |
15 | export default {
16 | getUsers,
17 | getUsersById,
18 | getUsersSearch,
19 | }
--------------------------------------------------------------------------------
/examples/spa/part6/src/common/constants.js:
--------------------------------------------------------------------------------
1 | const appConstants = {
2 | routes: {
3 | index: '/',
4 | posts: '/posts',
5 | postsSearch: '/posts/query/:query',
6 | usersSearch: '/users/query/:query',
7 | users: '/users',
8 | },
9 | search: {
10 | types: {
11 | post: 'post',
12 | user: 'user',
13 | }
14 | },
15 | lists: {
16 | types: {
17 | post: 'post',
18 | user: 'user',
19 | }
20 | }
21 | }
22 |
23 | export default appConstants
--------------------------------------------------------------------------------
/examples/spa/part6/src/components/index.js:
--------------------------------------------------------------------------------
1 | import './link-component'
2 | import './nav-component'
3 | import './user-avatar'
4 | import './post-component'
5 | import './user-component'
6 | import './list-component'
7 | import './pagination-component'
8 |
9 |
--------------------------------------------------------------------------------
/examples/spa/part6/src/index.js:
--------------------------------------------------------------------------------
1 | import './styles/main.scss'
2 | import initRouter from './router'
3 | import './components'
4 |
5 | initRouter()
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/spa/part6/src/pages/main.template:
--------------------------------------------------------------------------------
1 |
2 | Main template (new content)
--------------------------------------------------------------------------------
/examples/spa/part6/src/pages/posts.template:
--------------------------------------------------------------------------------
1 |
2 | Posts template
--------------------------------------------------------------------------------
/examples/spa/part6/src/pages/users.template:
--------------------------------------------------------------------------------
1 |
2 | Posts template
--------------------------------------------------------------------------------
/examples/spa/part6/src/service/posts.js:
--------------------------------------------------------------------------------
1 | const posts = new Map()
2 |
3 | export const getPost = (postId) => {
4 | return posts.get(postId)
5 | }
6 |
7 | export const setPost = (post) => {
8 | posts.set(post.id, post)
9 | }
10 |
11 | export default {
12 | getPost,
13 | setPost
14 | }
--------------------------------------------------------------------------------
/examples/spa/part6/src/service/users.js:
--------------------------------------------------------------------------------
1 | const users = new Map()
2 |
3 | export const getUser = (userId) => {
4 | return users.get(userId)
5 | }
6 |
7 | export const setUser = (user) => {
8 | users.set(user.id, user)
9 | }
10 |
11 | export default {
12 | getUser,
13 | setUser
14 | }
--------------------------------------------------------------------------------
/examples/spa/part6/src/styles/common.scss:
--------------------------------------------------------------------------------
1 |
2 | body{
3 | background-color: #fff;
4 | color: #000;
5 | }
6 |
--------------------------------------------------------------------------------
/examples/spa/part6/src/styles/main.scss:
--------------------------------------------------------------------------------
1 | @import 'common.scss';
2 |
3 | body{
4 | background-color: #fff;
5 | color: #000;
6 | }
7 |
--------------------------------------------------------------------------------
/examples/spa/part6/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import { ViteAliases } from "vite-aliases";
3 | import legacy from "@vitejs/plugin-legacy"
4 | import TemplateLoader from './plugins/vite-template-plugin'
5 |
6 | export default defineConfig({
7 | build: {
8 | target: 'es2017',
9 | outDir: 'build',
10 | },
11 | server: {
12 | port: 3000,
13 | host: '0.0.0.0',
14 | hmr: true,
15 | },
16 | plugins: [
17 | ViteAliases(),
18 | TemplateLoader(),
19 | legacy({
20 | targets: ['defaults', 'not IE 11'],
21 | })
22 | ],
23 | })
--------------------------------------------------------------------------------
/examples/spa/part7/README.md:
--------------------------------------------------------------------------------
1 | # SPA прилоежние на основе web компонентов.
2 |
3 | ## Как пользоваться
4 |
5 | npm install
6 | npm install -g json-server
7 | npm install -g http-server-spa
8 |
9 | #### Запуск локального REST API сервера
10 |
11 | npm run server
12 |
13 | #### Запуск приложения
14 |
15 | npm run start
16 |
17 |
18 | ## Команды для сборки дев и прод версий
19 |
20 | npm run build
21 | npm run ibuild-prod
22 |
23 | ## Build and run spa server
24 |
25 | npm run build // или npm run build-prod
26 | cd build
27 | http-server-spa . ./index.html 3000
28 |
29 | ## Видео с объяснением как это все работает здесь:
30 |
31 | https://youtu.be/eTaNwVqSmXk
32 |
33 |
34 | ## Другие видео по Vanilla js:
35 |
36 | - Введиние в Cordova, превращаем существующее приложение в мобильное https://youtu.be/O5mQRVTmUf4
37 |
38 | ## Полезные видео по настройке webpack:
39 |
40 | - Настройка горячей перезагрузки - https://youtu.be/oOpzkF2nU0s
41 |
42 | - Настройка сборки проекта с подгрузкой файлов css/scss/изображений - https://youtu.be/3B-NGZmMe-Y
43 |
44 | - Модульный принцип конфигурации проекта - https://youtu.be/fnUqyWyG5kk
45 |
46 |
--------------------------------------------------------------------------------
/examples/spa/part7/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SPA on VanillaJs (based on Web Components)
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/spa/part7/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "spa_example",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "vite",
8 | "build": "cross-env BUILD_TYPE=dev vite build",
9 | "serve": "vite preview --port 3000",
10 | "build-prod": "cross-env BUILD_TYPE=prod vite build",
11 | "server": "json-server --port 1111 ./db.json",
12 | "test": "echo \"Error: no test specified\" && exit 1"
13 | },
14 | "keywords": [],
15 | "author": "",
16 | "license": "ISC",
17 | "devDependencies": {
18 | "@vitejs/plugin-legacy": "^1.7.0",
19 | "cross-env": "^7.0.3",
20 | "sass": "^1.46.0",
21 | "vite": "^2.8.0",
22 | "vite-aliases": "^0.8.7"
23 | },
24 | "dependencies": {
25 | "route-parser": "0.0.5"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/examples/spa/part7/plugins/vite-template-plugin.js:
--------------------------------------------------------------------------------
1 | const fileRegex = /\.(template)$/
2 |
3 | export default function templatePlugin(){
4 | return {
5 | name: 'template-loader-plugin',
6 |
7 | transform(src, id) {
8 | if(fileRegex.test(id)) {
9 | return {
10 | code: `export default function template(props = {}){return \`${src}\`}`,
11 | map: null,
12 | }
13 | }
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/examples/spa/part7/src/api/commentsApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const getCommentsByPost = (postId, page) => {
4 | return baseApi.get(`/posts/${postId}/comments?_page=${page}&limit=10&_expand=user&_sort=createAt`)
5 | }
6 |
7 | export const getCommentsByUser = (userId, page) => {
8 | return baseApi.get(`/comments?userId=${userId}&_page=${page}&limit=10&_expand=user&_expand=post`)
9 | }
10 |
11 | export const getCommentsSearch = (search, page) => {
12 | return baseApi.get(`/comments?q=${search}&_page=${page}&limit=10&_expand=user&_expand=post`)
13 | }
14 |
15 | export default {
16 | getCommentsByPost,
17 | getCommentsByUser,
18 | }
--------------------------------------------------------------------------------
/examples/spa/part7/src/api/index.js:
--------------------------------------------------------------------------------
1 | export {default as postsApi } from './postsApi'
2 | export {default as usersApi } from './usersApi'
3 | export {default as commentsApi } from './commentsApi'
--------------------------------------------------------------------------------
/examples/spa/part7/src/api/postsApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const getPosts = (page) => {
4 | return baseApi.get(`/posts?_page=${page}&limit=10&_expand=user`)
5 | }
6 |
7 | export const getPostsByUser = (userId, page) => {
8 | return baseApi.get(`/posts?userId=${userId}&_page=${page}&limit=10&_expand=user`)
9 | }
10 |
11 | export const getPostById = (postId) => {
12 | return baseApi.get(`/posts/${postId}?_expand=user`)
13 | }
14 |
15 | export const getPostsSearch = (search, page) => {
16 | return baseApi.get(`/posts?q=${search}&_page=${page}&limit=10&_expand=user`)
17 | }
18 |
19 | export default {
20 | getPosts,
21 | getPostsByUser,
22 | getPostById,
23 | getPostsSearch,
24 | }
--------------------------------------------------------------------------------
/examples/spa/part7/src/api/usersApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const getUsers = (page) => {
4 | return baseApi.get(`/users?_page=${page}&limit=10`)
5 | }
6 |
7 | export const getUserById = (userId) => {
8 | return baseApi.get(`/users/${userId}`)
9 | }
10 |
11 | export const getUsersSearch = (search, page) => {
12 | return baseApi.get(`/users?q=${search}&_page=${page}&limit=10`)
13 | }
14 |
15 | export default {
16 | getUsers,
17 | getUserById,
18 | getUsersSearch,
19 | }
--------------------------------------------------------------------------------
/examples/spa/part7/src/common/constants.js:
--------------------------------------------------------------------------------
1 | const appConstants = {
2 | routes: {
3 | index: '/',
4 | posts: '/posts',
5 | postsSearch: '/posts/query/:query',
6 | usersSearch: '/users/query/:query',
7 | users: '/users',
8 | post: '/post/:post',
9 | user: '/user/:user',
10 | userPosts: '/user/:user/posts',
11 | userComments: '/user/:user/comments',
12 | },
13 | search: {
14 | types: {
15 | post: 'post',
16 | user: 'user',
17 | }
18 | },
19 | lists: {
20 | types: {
21 | post: 'post',
22 | user: 'user',
23 | comment: 'comment',
24 | }
25 | }
26 | }
27 |
28 | export default appConstants
--------------------------------------------------------------------------------
/examples/spa/part7/src/components/index.js:
--------------------------------------------------------------------------------
1 | import './link-component'
2 | import './nav-component'
3 | import './user-avatar'
4 | import './post-component'
5 | import './user-component'
6 | import './list-component'
7 | import './pagination-component'
8 | import './post-detail'
9 | import './comment-component'
10 | import './date-formatted'
11 |
12 |
--------------------------------------------------------------------------------
/examples/spa/part7/src/index.js:
--------------------------------------------------------------------------------
1 | import './styles/main.scss'
2 | import initRouter from './router'
3 | import './components'
4 |
5 | initRouter()
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/spa/part7/src/pages/main.template:
--------------------------------------------------------------------------------
1 |
2 | Main template (new content)
--------------------------------------------------------------------------------
/examples/spa/part7/src/pages/post.template:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/examples/spa/part7/src/pages/posts.template:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/examples/spa/part7/src/pages/user.template:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/examples/spa/part7/src/pages/userComments.template:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/examples/spa/part7/src/pages/userPosts.template:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/examples/spa/part7/src/pages/users.template:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/examples/spa/part7/src/service/comments.js:
--------------------------------------------------------------------------------
1 | const comments = new Map()
2 |
3 | export const getComment = (commentId) => {
4 | return comments.get(commentId)
5 | }
6 |
7 | export const setComment = (comment) => {
8 | return comments.set(comment.id, comment)
9 | }
10 |
11 | export default {
12 | getComment,
13 | setComment,
14 | }
--------------------------------------------------------------------------------
/examples/spa/part7/src/service/posts.js:
--------------------------------------------------------------------------------
1 | const posts = new Map()
2 |
3 | export const getPost = (postId) => {
4 | return posts.get(postId)
5 | }
6 |
7 | export const setPost = (post) => {
8 | posts.set(post.id, post)
9 | }
10 |
11 | export default {
12 | getPost,
13 | setPost
14 | }
--------------------------------------------------------------------------------
/examples/spa/part7/src/service/users.js:
--------------------------------------------------------------------------------
1 | const users = new Map()
2 |
3 | export const getUser = (userId) => {
4 | return users.get(userId)
5 | }
6 |
7 | export const setUser = (user) => {
8 | users.set(user.id, user)
9 | }
10 |
11 | export default {
12 | getUser,
13 | setUser
14 | }
--------------------------------------------------------------------------------
/examples/spa/part7/src/styles/common.scss:
--------------------------------------------------------------------------------
1 |
2 | body{
3 | background-color: #fff;
4 | color: #000;
5 | }
6 |
--------------------------------------------------------------------------------
/examples/spa/part7/src/styles/main.scss:
--------------------------------------------------------------------------------
1 | @import 'common.scss';
2 |
3 | body{
4 | background-color: #fff;
5 | color: #000;
6 | }
7 |
--------------------------------------------------------------------------------
/examples/spa/part7/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import { ViteAliases } from "vite-aliases";
3 | import legacy from "@vitejs/plugin-legacy"
4 | import TemplateLoader from './plugins/vite-template-plugin'
5 |
6 | export default defineConfig({
7 | build: {
8 | target: 'es2017',
9 | outDir: 'build',
10 | },
11 | server: {
12 | port: 3000,
13 | host: '0.0.0.0',
14 | hmr: true,
15 | },
16 | plugins: [
17 | ViteAliases(),
18 | TemplateLoader(),
19 | legacy({
20 | targets: ['defaults', 'not IE 11'],
21 | })
22 | ],
23 | })
--------------------------------------------------------------------------------
/examples/spa/part8/README.md:
--------------------------------------------------------------------------------
1 | # SPA приложение на основе web компонентов.
2 |
3 | ## Как пользоваться
4 |
5 | npm install
6 | npm install -g json-server
7 | npm install -g http-server-spa
8 |
9 | #### Запуск локального REST API сервера
10 |
11 | npm run server
12 |
13 | #### Запуск приложения
14 |
15 | npm run start
16 |
17 |
18 | ## Команды для сборки дев и прод версий
19 |
20 | npm run build
21 | npm run ibuild-prod
22 |
23 | ## Build and run spa server
24 |
25 | npm run build // или npm run build-prod
26 | cd build
27 | http-server-spa . ./index.html 3000
28 |
29 | ## Видео с объяснением как это все работает здесь:
30 |
31 | https://youtu.be/HIdYceoPhlg
32 |
33 |
34 | ## Другие видео по Vanilla js:
35 |
36 | - Введиние в Cordova, превращаем существующее приложение в мобильное https://youtu.be/O5mQRVTmUf4
37 |
38 | ## Полезные видео по настройке webpack:
39 |
40 | - Настройка горячей перезагрузки - https://youtu.be/oOpzkF2nU0s
41 |
42 | - Настройка сборки проекта с подгрузкой файлов css/scss/изображений - https://youtu.be/3B-NGZmMe-Y
43 |
44 | - Модульный принцип конфигурации проекта - https://youtu.be/fnUqyWyG5kk
45 |
46 |
--------------------------------------------------------------------------------
/examples/spa/part8/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "spa_example",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "vite",
8 | "build": "cross-env BUILD_TYPE=dev vite build",
9 | "serve": "vite preview --port 3000",
10 | "build-prod": "cross-env BUILD_TYPE=prod vite build",
11 | "server": "json-server --port 1111 ./db.json",
12 | "test": "echo \"Error: no test specified\" && exit 1"
13 | },
14 | "keywords": [],
15 | "author": "",
16 | "license": "ISC",
17 | "devDependencies": {
18 | "@vitejs/plugin-legacy": "^1.7.0",
19 | "cross-env": "^7.0.3",
20 | "sass": "^1.46.0",
21 | "vite": "^2.8.0",
22 | "vite-aliases": "^0.8.7"
23 | },
24 | "dependencies": {
25 | "route-parser": "0.0.5"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/examples/spa/part8/plugins/vite-template-plugin.js:
--------------------------------------------------------------------------------
1 | const fileRegex = /\.(template)$/
2 |
3 | export default function templatePlugin(){
4 | return {
5 | name: 'template-loader-plugin',
6 |
7 | transform(src, id) {
8 | if(fileRegex.test(id)) {
9 | return {
10 | code: `export default function template(props = {}){return \`${src}\`}`,
11 | map: null,
12 | }
13 | }
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/examples/spa/part8/src/api/commentsApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const getCommentsByPost = (postId, page) => {
4 | return baseApi.get(`/posts/${postId}/comments?_page=${page}&limit=10&_expand=user&_sort=createAt`)
5 | }
6 |
7 | export const getCommentsByUser = (userId, page) => {
8 | return baseApi.get(`/comments?userId=${userId}&_page=${page}&limit=10&_expand=user&_expand=post`)
9 | }
10 |
11 | export const getCommentsSearch = (search, page) => {
12 | return baseApi.get(`/comments?q=${search}&_page=${page}&limit=10&_expand=user&_expand=post`)
13 | }
14 |
15 | export default {
16 | getCommentsByPost,
17 | getCommentsByUser,
18 | }
--------------------------------------------------------------------------------
/examples/spa/part8/src/api/index.js:
--------------------------------------------------------------------------------
1 | export {default as postsApi } from './postsApi'
2 | export {default as usersApi } from './usersApi'
3 | export {default as commentsApi } from './commentsApi'
--------------------------------------------------------------------------------
/examples/spa/part8/src/api/postsApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const getPosts = (page) => {
4 | return baseApi.get(`/posts?_page=${page}&limit=10&_expand=user`)
5 | }
6 |
7 | export const getPostsByUser = (userId, page) => {
8 | return baseApi.get(`/posts?userId=${userId}&_page=${page}&limit=10&_expand=user`)
9 | }
10 |
11 | export const getPostById = (postId) => {
12 | return baseApi.get(`/posts/${postId}?_expand=user`)
13 | }
14 |
15 | export const getPostsSearch = (search, page) => {
16 | return baseApi.get(`/posts?q=${search}&_page=${page}&limit=10&_expand=user`)
17 | }
18 |
19 | export default {
20 | getPosts,
21 | getPostsByUser,
22 | getPostById,
23 | getPostsSearch,
24 | }
--------------------------------------------------------------------------------
/examples/spa/part8/src/api/usersApi.js:
--------------------------------------------------------------------------------
1 | import baseApi from './baseApi'
2 |
3 | export const getUsers = (page) => {
4 | return baseApi.get(`/users?_page=${page}&limit=10`)
5 | }
6 |
7 | export const getUserById = (userId) => {
8 | return baseApi.get(`/users/${userId}`)
9 | }
10 |
11 | export const getUsersSearch = (search, page) => {
12 | return baseApi.get(`/users?q=${search}&_page=${page}&limit=10`)
13 | }
14 |
15 | export default {
16 | getUsers,
17 | getUserById,
18 | getUsersSearch,
19 | }
--------------------------------------------------------------------------------
/examples/spa/part8/src/common/constants.js:
--------------------------------------------------------------------------------
1 | const appConstants = {
2 | routes: {
3 | index: '/',
4 | posts: '/posts',
5 | postsSearch: '/posts/query/:query',
6 | usersSearch: '/users/query/:query',
7 | users: '/users',
8 | post: '/post/:post',
9 | user: '/user/:user',
10 | userPosts: '/user/:user/posts',
11 | userComments: '/user/:user/comments',
12 | },
13 | search: {
14 | types: {
15 | post: 'post',
16 | user: 'user',
17 | }
18 | },
19 | lists: {
20 | types: {
21 | post: 'post',
22 | user: 'user',
23 | comment: 'comment',
24 | }
25 | }
26 | }
27 |
28 | export default appConstants
--------------------------------------------------------------------------------
/examples/spa/part8/src/components/index.js:
--------------------------------------------------------------------------------
1 | import './link-component'
2 | import './nav-component'
3 | import './user-avatar'
4 | import './post-component'
5 | import './user-component'
6 | import './list-component'
7 | import './pagination-component'
8 | import './post-detail'
9 | import './comment-component'
10 | import './date-formatted'
11 | import './app-component'
12 | import './fake-form'
13 | import './modal-dialog'
14 |
15 |
--------------------------------------------------------------------------------
/examples/spa/part8/src/index.js:
--------------------------------------------------------------------------------
1 | import './styles/main.scss'
2 | import initRouter from './router'
3 | import './components'
4 |
5 | initRouter()
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/spa/part8/src/pages/main.template:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 | ${props.topBlock || ''}
10 | ${props.leftBlock || ''}
11 | ${props.rightBlock || ''}
12 | ${props.bottomBlock || ''}
13 |
--------------------------------------------------------------------------------
/examples/spa/part8/src/pages/main/bottom.template:
--------------------------------------------------------------------------------
1 |
25 |
26 | ${ [...Array(20).keys()].map((block)=>{
27 | return `
Bottom block ${block+1}
`
28 | }).join('\n')}
29 |
--------------------------------------------------------------------------------
/examples/spa/part8/src/pages/main/right.template:
--------------------------------------------------------------------------------
1 |
30 |
31 |
32 | ${ [...Array(12).keys()].map((block)=>{
33 | return `
34 |
35 |
`
36 | }).join('\n')}
37 |
38 |
39 |
--------------------------------------------------------------------------------
/examples/spa/part8/src/pages/main/top.template:
--------------------------------------------------------------------------------
1 |
23 |
24 | ${ [...Array(10).keys()].map((block)=>{
25 | return `
Top block ${block+1}
`
26 | }).join('\n')}
27 |
--------------------------------------------------------------------------------
/examples/spa/part8/src/pages/post.template:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/examples/spa/part8/src/pages/posts.template:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/examples/spa/part8/src/pages/user.template:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/examples/spa/part8/src/pages/userComments.template:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/examples/spa/part8/src/pages/userPosts.template:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/examples/spa/part8/src/pages/users.template:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/examples/spa/part8/src/service/comments.js:
--------------------------------------------------------------------------------
1 | const comments = new Map()
2 |
3 | export const getComment = (commentId) => {
4 | return comments.get(commentId)
5 | }
6 |
7 | export const setComment = (comment) => {
8 | return comments.set(comment.id, comment)
9 | }
10 |
11 | export default {
12 | getComment,
13 | setComment,
14 | }
--------------------------------------------------------------------------------
/examples/spa/part8/src/service/posts.js:
--------------------------------------------------------------------------------
1 | const posts = new Map()
2 |
3 | export const getPost = (postId) => {
4 | return posts.get(postId)
5 | }
6 |
7 | export const setPost = (post) => {
8 | posts.set(post.id, post)
9 | }
10 |
11 | export default {
12 | getPost,
13 | setPost
14 | }
--------------------------------------------------------------------------------
/examples/spa/part8/src/service/users.js:
--------------------------------------------------------------------------------
1 | const users = new Map()
2 |
3 | export const getUser = (userId) => {
4 | return users.get(userId)
5 | }
6 |
7 | export const setUser = (user) => {
8 | users.set(user.id, user)
9 | }
10 |
11 | export default {
12 | getUser,
13 | setUser
14 | }
--------------------------------------------------------------------------------
/examples/spa/part8/src/styles/common.scss:
--------------------------------------------------------------------------------
1 |
2 | body{
3 | background-color: #fff;
4 | color: #000;
5 | }
6 |
--------------------------------------------------------------------------------
/examples/spa/part8/src/styles/main.scss:
--------------------------------------------------------------------------------
1 | @import 'common.scss';
2 |
3 | body{
4 | background-color: #fff;
5 | color: #000;
6 | }
7 |
--------------------------------------------------------------------------------
/examples/spa/part8/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import { ViteAliases } from "vite-aliases";
3 | import legacy from "@vitejs/plugin-legacy"
4 | import TemplateLoader from './plugins/vite-template-plugin'
5 |
6 | export default defineConfig({
7 | build: {
8 | target: 'es2017',
9 | outDir: 'build',
10 | },
11 | server: {
12 | port: 3000,
13 | host: '0.0.0.0',
14 | hmr: true,
15 | },
16 | plugins: [
17 | ViteAliases(),
18 | TemplateLoader(),
19 | legacy({
20 | targets: ['defaults', 'not IE 11'],
21 | })
22 | ],
23 | })
--------------------------------------------------------------------------------