{"id":18070091,"url":"https://github.com/polatengin/madrid","last_synced_at":"2026-05-12T07:41:52.831Z","repository":{"id":144742190,"uuid":"192622203","full_name":"polatengin/madrid","owner":"polatengin","description":"Web app similar to keycode.info","archived":false,"fork":false,"pushed_at":"2024-08-28T15:25:41.000Z","size":60,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-11T13:47:44.016Z","etag":null,"topics":["devcontainer","dockerfile","github-actions","keycodes","netlify","typescript","webpack"],"latest_commit_sha":null,"homepage":"https://polatengin-madrid.netlify.com/","language":"Dockerfile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/polatengin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-06-18T22:47:57.000Z","updated_at":"2020-05-06T08:12:34.000Z","dependencies_parsed_at":null,"dependency_job_id":"dab428d5-9599-472c-ade1-45b5a4746b81","html_url":"https://github.com/polatengin/madrid","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polatengin%2Fmadrid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polatengin%2Fmadrid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polatengin%2Fmadrid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polatengin%2Fmadrid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/polatengin","download_url":"https://codeload.github.com/polatengin/madrid/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247369927,"owners_count":20927927,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["devcontainer","dockerfile","github-actions","keycodes","netlify","typescript","webpack"],"created_at":"2024-10-31T08:24:04.327Z","updated_at":"2026-05-12T07:41:52.781Z","avatar_url":"https://github.com/polatengin.png","language":"Dockerfile","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Web page similar to [keycode.info](https://keycode.info)\r\n\r\n[![Netlify Status](https://api.netlify.com/api/v1/badges/ab879ede-6acc-4f7e-9337-44e14858ba45/deploy-status)](https://app.netlify.com/sites/polatengin-madrid/deploys)\r\n\r\n[![GitHub Actions Status](https://github.com/polatengin/madrid/workflows/BuildAndPublish/badge.svg)](https://github.com/polatengin/madrid/workflows/ci-and-cd)\r\n\r\nYou can use the running version of this project at [https://polatengin-madrid.netlify.com/](https://polatengin-madrid.netlify.com/)\r\n\r\nThe reason I made this project;\r\n\r\n* To learn how to inject _javascript_ and _css_ into an _html_ page by configuring [Webpack](https://github.com/webpack/webpack) and [PostCSS](https://github.com/postcss/postcss)\r\n\r\n* Experience and understand how browsers are processing keyboard events\r\n\r\n* Create and run a pipeline with [GitHub Actions](https://github.com/features/actions)\r\n\r\n* Gain the habit of project development within [Visual Studio Code DevContainer](https://code.visualstudio.com/docs/remote/containers)\r\n\r\nTechnologies I used in this project are;\r\n\r\n* Typescript\r\n* WebPack\r\n  * PostCSS\r\n* GitHub Actions\r\n* Docker\r\n* Netlify\r\n* DevContainers\r\n\r\nTo create the project, let's run the following command in an empty directory\r\n\r\n```bash\r\nnpm init --force\r\n```\r\n\r\nNow, open a _Terminal_ window and run the following command to add the `keycode` npm package to [package.json](./package.json)\r\n\r\n```bash\r\nnpm i keycode --save\r\n```\r\n\r\nNow, we can _require_ the `keycode` module in [src/index.ts](./src/index.ts)\r\n\r\n```typescript\r\nconst keycode = require('keycode');\r\n```\r\n\r\nBy attaching to the `keydown` _event_ of the `window` _global_ object, we can capture all the pressed keys in the entire browser window.\r\n\r\n```typescript\r\nwindow.addEventListener('keydown', (e) =\u003e {\r\n});\r\n```\r\n\r\nBy calling the `stopPropagation()` and `preventDefault()` methods in the _event_ handler, we prevent the keys from being processed by the browser.\r\n\r\n```typescript\r\nvar index = document.createElement('li');\r\nindex.innerHTML = `${currentIndex}`;\r\n\r\nvar key = document.createElement('li');\r\nkey.innerHTML = keycode(e);\r\n\r\nvar keyCode = document.createElement('li');\r\nkeyCode.innerHTML = `${e.keyCode}`;\r\n\r\nvar shift = document.createElement('li');\r\nshift.innerHTML = e.shiftKey ? '✓' : '⨯';\r\n\r\nvar control = document.createElement('li');\r\ncontrol.innerHTML = e.ctrlKey ? '✓' : '⨯';\r\n\r\nvar alt = document.createElement('li');\r\nalt.innerHTML = e.altKey ? '✓' : '⨯';\r\n\r\nvar item = document.createElement('ul');\r\nitem.appendChild(index);\r\nitem.appendChild(key);\r\nitem.appendChild(keyCode);\r\nitem.appendChild(shift);\r\nitem.appendChild(control);\r\nitem.appendChild(alt);\r\n\r\narticle.insertAdjacentElement('afterbegin', item);\r\n```\r\n\r\nSo, even if the keys like `F5`, `F12` are pressed, the browser will not process them.\r\n\r\nWe add the required _html_ code into the [./src/index.html](./src/index.html) file so that a table will appear on the screen.\r\n\r\n```html\r\n\u003cmain class=\"row title\"\u003e\r\n  \u003cul\u003e\r\n    \u003cli\u003e#\u003c/li\u003e\r\n    \u003cli\u003eKey\u003c/li\u003e\r\n    \u003cli\u003eKey Code\u003c/li\u003e\r\n    \u003cli\u003eShift\u003c/li\u003e\r\n    \u003cli\u003eControl\u003c/li\u003e\r\n    \u003cli\u003eAlt\u003c/li\u003e\r\n  \u003c/ul\u003e\r\n\u003c/main\u003e\r\n\u003carticle class=\"row item\"\u003e\r\n\u003c/article\u003e\r\n```\r\n\r\nAlso, we're providing the same editor settings to the developers (_space/tab_, _end-of-line-character_, etc.) with the [.editorconfig](./.editorconfig) file.\r\n\r\nIn the [tsconfig.json](./tsconfig.json) file, we give the `compilerOptions.outDir` property value of `./dist`, so that when the [webpack](https://webpack.js.org/) compiles, the compiled files will be created in the `./dist` folder.\r\n\r\nIn the [./src/index.ts](./src/index.ts) file, we capture all `keydown` events via the `window.addEventListener()` method.\r\n\r\nWe use the following two lines to prevent any keydown events we capture from being captured by the browser.\r\n\r\n```typescript\r\ne.stopPropagation();\r\ne.preventDefault();\r\n```\r\n\r\nWe added the following `plugins` into the [webpack.config.js](./webpack.config.js) file\r\n\r\n* With [CopyWebpackPlugin](https://webpack.js.org/plugins/copy-webpack-plugin/), we can copy files based on their extensions\r\n\r\n* With [HtmlMinifierPlugin](https://www.npmjs.com/package/html-minifier-webpack-plugin), we can compress the html files\r\n\r\n* With [HtmlWebpackPlugin](https://webpack.js.org/plugins/html-webpack-plugin/), the `bundle.js` file that is generated by compiling the `ts` files, and it's added into the [index.html](./src/index.html) file\r\n\r\nAlso, with the [hash](https://github.com/jantimon/html-webpack-plugin#options) option of the [HtmlWebpackPlugin](https://webpack.js.org/plugins/html-webpack-plugin/) plugin, we added the compiled ts files into the [index.html](./src/index.html) as `bundle.js?{HASH}`.\r\n\r\nThanks to Multi-Layered [Dockerfile](./Dockerfile), we compile the project in [node:13.10.1-buster](https://hub.docker.com/_/node/) image, then move all compiled files to [nginx:1.17.0-alpine](https://hub.docker.com/_/nginx/) image and expose them.\r\n\r\nAt the end, we have a _Docker Image_ that takes about _20MB_ in size.\r\n\r\n![Sample Screenshot](./sample-screenshot.gif \"Sample Screenshot\")\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolatengin%2Fmadrid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpolatengin%2Fmadrid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolatengin%2Fmadrid/lists"}