├── README.md ├── css-terminal.js └── index.html /README.md: -------------------------------------------------------------------------------- 1 | ___ ___ ___ 2 | / __/ __/ __| 3 | | (__\__ \__ \ 4 | \___|___/___/ 5 | T E R M I N A L 6 | 7 | #### Description 8 | 9 | [CSS Terminal][projecthome] is a bookmarklet that allows you to inject CSS rules directly 10 | into a live web page. It's handy for rapid CSS development, prototyping and debugging. 11 | 12 | #### Homepage 13 | 14 | You can read about it, see it in action and install it at the 15 | [project home page][projecthome]. 16 | 17 | #### About 18 | 19 | The CSS Terminal bookmarklet was written by Ben Barber while working at 20 | [i2rd / Vipa Solutions][vipa]. The code was generously donated to the 21 | community under the MIT license. 22 | 23 | The [source code and project page][projectsource] are hosted on [GitHub][github]. 24 | 25 | [projecthome]: https://barberboy.github.io/css-terminal/ 26 | [vipa]: http://www.vipasolutions.com 27 | [github]: http://github.com 28 | [projectsource]: https://github.com/barberboy/css-terminal 29 | 30 | #### License 31 | 32 | Copyright (C) 2010-2023 by Interactive Information Research and Development 33 | (i2rd) 34 | 35 | Permission is hereby granted, free of charge, to any person obtaining a copy 36 | of this software and associated documentation files (the "Software"), to deal 37 | in the Software without restriction, including without limitation the rights 38 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 39 | copies of the Software, and to permit persons to whom the Software is 40 | furnished to do so, subject to the following conditions: 41 | 42 | The above copyright notice and this permission notice shall be included in 43 | all copies or substantial portions of the Software. 44 | 45 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 46 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 47 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 48 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 49 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 50 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 51 | THE SOFTWARE. 52 | -------------------------------------------------------------------------------- /css-terminal.js: -------------------------------------------------------------------------------- 1 | javascript: (function () { 2 | var terminal = document.getElementById("css-terminal"); 3 | if (!terminal) { 4 | var keymap = { enter: 13, escape: 27, semicolon: 186, forwardSlash: 191, period: 190 }; 5 | var body = document.getElementsByTagName("body")[0]; 6 | var previousStyles = unescape(localStorage.getItem("css-terminal") || ""); 7 | var terminal = newElement("textarea", { 8 | id: "css-terminal", 9 | value: previousStyles, 10 | autocorrect: "off", 11 | autocapitalize: "off" 12 | }); 13 | var terminalStyles = newElement("style", { 14 | id: "css-terminal-css", 15 | innerHTML: ` 16 | #css-terminal { 17 | background: transparent url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAndJREFUOMuNkr1LXEEUxX8zb3b3ze7KopDCJFVIqRBilUKCNgFZNFVAAmthJWJvVsQiTf4HQdBaEKwsFgL5kKR4YJr0msDDoMmukfF9zUya7INAIDlw4XIunHvu4Yq9vb2Ndrv9Qmtd4x9wzuG9xzmHMSY5Ojp6yfn5+Tf/n3DOeeect9Z6a60/PT09F8aY5ODgoLa7u8vMzAz/g16vx8bGBhMTE4kckk/abcbv3sUYgzGGZrPJ+vo6xhharRadTqec9Xq94SleAl4IwVW/z6PHj3nW6ZAVBdPT02xtbRHHMSsrK2W/vLxMt9slTVOMMVYCSCl5//YtH4+PuTU+TpplNBoNoigijmM2NzfpdrvEcczq6ipLS0ukaUpRFF4JIRBCMDs3h/We50+f8uP7d968fk0URUxNTbG9vc3Ozg5xHBNFEbOzs6ytrQEgkiQxh4eHenFxEaUUrVaLe/fvM/HgAQL48O4dd27f5uTkBABjDFdXV+zv7zM5OflTCSGQUmKtxVpLv9/n8vKSL2dnCCEYDAZ8OTujKAqyLCPLMgC893jvUcMQAbTWhGHIz8GAz58+IaVEACMjI+R5TpZlJEmCMQbnHABKSokQAq01jUaDMAwJw5BKpUIQBABYa8nznDRNkVL+6WAYotYarTX1ep0wDKlWqyilSoEsy1BKIYTAe18+lRqqhWFYCtTrdWq1GkEQIISgKIpyu/cea23pQjnnaDabzM/Ply5qtdpfT0iShJubG5IkQSmFcw5xfX39VQhxx1pLURR/1L+40dHR02BhYSEYGxt7+NtSDuRALqUsKwiCXCmVK6XySqWSV6vVXGs9uLi4ePULSRiabTd6gRQAAAAASUVORK5CYII=') no-repeat top right; 18 | font-family: monospace; 19 | position: fixed; 20 | top: 0; 21 | right: 0; 22 | color: transparent; 23 | z-index: 100000; 24 | border: 0; 25 | width: 32px; 26 | height: 32px; 27 | max-height: 32px; 28 | overflow: hidden; 29 | cursor: pointer; 30 | resize: none; 31 | } 32 | #css-terminal:focus { 33 | background: rgba(0,0,0,.75); 34 | border: 2px solid rgba(0,0,0,.1); 35 | color: white; 36 | cursor: text; 37 | height: 25em; 38 | max-height: none; 39 | width: 40em; 40 | outline: none; 41 | overflow: auto; 42 | padding: .25em; 43 | resize: both; 44 | }` 45 | }); 46 | var terminalOutput = newElement("style", { 47 | id: "css-terminal-output", 48 | innerHTML: previousStyles 49 | }); 50 | 51 | body.appendChild(terminalStyles); 52 | body.appendChild(terminal); 53 | body.appendChild(terminalOutput); 54 | 55 | terminal.addEventListener("keydown", function (evt) { 56 | evt.stopPropagation(); 57 | var keyCode = evt.keyCode; 58 | if (keyCode === keymap.enter || keyCode === keymap.semicolon && !evt.shiftKey) { 59 | terminalOutput.innerHTML = this.value; 60 | localStorage.setItem("css-terminal", escape(this.value)); 61 | } 62 | if (keymap.escape === keyCode || evt.ctrlKey && keyCode === keymap.forwardSlash) { 63 | return terminal.blur(); 64 | } 65 | }, true); 66 | 67 | window.addEventListener("keydown", function ({ keyCode, ctrlKey }) { 68 | /* ctrl + / activation shortcut */ 69 | if (ctrlKey && keyCode === keymap.forwardSlash) { 70 | terminal.focus(); 71 | } 72 | /* ctrl + . to make an element contenteditable */ 73 | if (ctrlKey && keyCode === keymap.period) { 74 | body.addEventListener("click", makeContenteditable, true); 75 | } 76 | }); 77 | 78 | function makeContenteditable(evt) { 79 | evt.preventDefault(); 80 | evt.stopPropagation(); 81 | 82 | evt.target.setAttribute("contenteditable", true); 83 | evt.target.focus(); 84 | 85 | /* Clean up event listeners */ 86 | body.removeEventListener("click", makeContenteditable, true); 87 | evt.target.addEventListener("blur", function disableContentEditable() { 88 | evt.target.removeAttribute("contenteditable"); 89 | evt.target.removeEventListener("blur", disableContentEditable); 90 | }); 91 | } 92 | 93 | function newElement(tagname, props) { 94 | var el = document.createElement(tagname); 95 | for (var i in props) { 96 | el[i] = props[i]; 97 | } 98 | return el; 99 | } 100 | } 101 | 102 | terminal.focus(); 103 | })(); -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CSS Terminal 6 | 7 | 9 | 39 | 44 | 45 | 46 | 47 |
48 |

CSS Terminal

49 |

CSS Terminal is a bookmarklet that allows you to inject CSS rules directly into a live web page. It's handy 50 | for rapid CSS development, prototyping and debugging.

51 |

52 | Wanna see it in action?
Click here 👇 53 |

54 |

55 | CSS 57 | Terminal 58 |

59 |

60 | Write CSS in the terminal (the dark gray box) and those styles will be applied to the page. 61 |

62 |

Install

63 |

64 | You can install the CSS Terminal bookmarklet in your browser by dragging the CSS 65 | Terminal link above 👆 to your browser's bookmarks toolbar. You may need to first make 66 | the toolbar visible by clicking View -> Always Show Bookmarks Bar or pressing 67 | Command+Shift+B. 68 |

69 |

Usage Notes

70 |

71 | Once you've added the bookmarklet to your bookmarks toolbar, you can click the CSS Terminal bookmark 72 | to activate it on any website you visit. Write CSS in the terminal and those styles will be applied to the 73 | page when you enter a semicolon or hit the Enter key. You can also hit 74 | Command+Enter (on Mac) or Ctrl+Enter to apply the styles. 75 |

76 |

77 | Pressing Esc or Tab will collapse the terminal. You can reactivate the 78 | terminal by clicking the bookmark again, clicking the CSS Terminal 81 | icon in the top right corner of the page, or pressing the keyboard shortcut Ctrl+/. 82 |

83 |

84 | If you reload/refresh your page, your custom CSS rules will no longer apply. However, when you reactivate 85 | the terminal, your last set of rules are reapplied and you can continue editing. 86 |

87 |

88 | The CSS Terminal uses local storage to save your custom CSS on a per site basis. This means 89 | that it will store your custom styles for ajaxian.com seperate from alistapart.com. 90 |

91 |

92 | To quickly prototype content changes, press Ctrl+. and click on the part of 93 | the page you'd like to change. CSS Terminal will make that element's content editable. 94 | Note: these content edits are *not* persisted; they will be lost when the page is reloaded. 95 |

96 |

97 | About CSS Terminal 98 |

99 |

100 | The CSS Terminal bookmarklet was written by Ben Barber and is released under the MIT License. 101 | The source code and project page are hosted on GitHub. 103 |

104 |
105 | 106 | 107 | --------------------------------------------------------------------------------