├── README.md ├── css └── cssterm.css ├── demo.html ├── demo.png └── scripts └── cssterm.js /README.md: -------------------------------------------------------------------------------- 1 | # CSSTerm 2 | 3 | Easy method to display a linux terminal on a webpage using pure CSS, powered by jQuery. 4 | 5 | ## Installation 6 | 7 | Place css and javascript files into your existing webpage, including a copy of jQuery 8 | 9 | ```html 10 | 11 | 12 | 13 | 14 | 15 | ``` 16 | 17 | ## Example 18 | 19 | Full Terminal Window html: 20 | 21 | ```html 22 |
23 | $ uname -a 24 | Linux ThinkPad-X230.localdomain 3.9.6-301.fc19.x86_64 #1 SMP Mon Jun 17 14:26:26 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux 25 | 26 | # dmesg | grep sd 27 | [135587.413741] sd 27:0:0:0: Attached scsi generic sg1 type 0 28 | [135587.416697] sd 27:0:0:0: [sdb] 2007040 512-byte logical blocks: (1.02 GB/980 MiB) 29 | [135587.418130] sd 27:0:0:0: [sdb] Write Protect is off 30 | [135587.418140] sd 27:0:0:0: [sdb] Mode Sense: 03 00 00 00 31 | [135587.418944] sd 27:0:0:0: [sdb] No Caching mode page present 32 | [135587.418947] sd 27:0:0:0: [sdb] Assuming drive cache: write through 33 | [135587.423205] sd 27:0:0:0: [sdb] No Caching mode page present 34 | [135587.423211] sd 27:0:0:0: [sdb] Assuming drive cache: write through 35 | [135587.424119] sdb: sdb1 sdb2 36 | [135587.428088] sd 27:0:0:0: [sdb] No Caching mode page present 37 | [135587.428094] sd 27:0:0:0: [sdb] Assuming drive cache: write through 38 | [135587.428098] sd 27:0:0:0: [sdb] Attached SCSI removable disk 39 | [135588.336077] SELinux: initialized (dev sdb1, type iso9660), uses genfs_contexts 40 | 41 | # mkfs.ext4 /dev/sdb1 42 | mke2fs 1.41.12 (17-May-2010) 43 | Filesystem label= 44 | OS type: Linux 45 | Block size=4096 (log=2) 46 | Fragment size=4096 (log=2) 47 | Stride=0 blocks, Stripe width=0 blocks 48 | 245280 inodes, 979456 blocks 49 | 48972 blocks (5.00%) reserved for the super user 50 | First data block=0 51 | Maximum filesystem blocks=1006632960 52 | 30 block groups 53 | 32768 blocks per group, 32768 fragments per group 54 | 8176 inodes per group 55 | Superblock backups stored on blocks: 56 | 32768, 98304, 163840, 229376, 294912, 819200, 884736 57 | 58 | Writing inode tables: done 59 | Creating journal (16384 blocks): done 60 | Writing superblocks and filesystem accounting information: done 61 | 62 | This filesystem will be automatically checked every 20 mounts or 63 | 180 days, whichever comes first. Use tune2fs -c or -i to override. 64 |
65 | 66 | ``` 67 | 68 | output: 69 | 70 | ![](https://raw.github.com/ignatenkobrain/cssterm/master/demo.png) 71 | 72 | ## Substitution 73 | 74 | The following replacements will be made if found at the beginning of a line: 75 | 76 | - `lines that start with "#" will be treated as a root command` 77 | - `lines that start with "!" will be replaced as a comment` 78 | - `include line breaks by placing a space (" ") on an empty line` 79 | - `everything else treated as standard output` 80 | 81 | ##ToDo 82 | 83 | 1. Testing.. Testing.. Testing.. 84 | 85 | ##Thanks 86 | 87 | Big Thank-You to [Dom Briggs](http://cssdeck.com/user/hallodom) over at CSSDeck for his [Pure CSS OSX Terminal](http://cssdeck.com/labs/pure-css-osx-terminal) work 88 | 89 | Big Thank-You to [Igor Gnatenko](https://github.com/ignatenkobrain) for his updates to this project! 90 | -------------------------------------------------------------------------------- /css/cssterm.css: -------------------------------------------------------------------------------- 1 | /*----FONTS----*/ 2 | @import url(http://fonts.googleapis.com/css?family=Cantarell:700|Open+Sans:300&subset=cyrillic-ext); 3 | 4 | /*--TERMINAL HOLDER--*/ 5 | #terminal-window{ 6 | width: 98%; 7 | margin-top:40px; 8 | margin-left: auto; 9 | margin-right: auto; 10 | margin-bottom: 40px; 11 | min-width: 500px; 12 | background: #fff; 13 | border-radius: 5px; 14 | box-shadow: 0px 0px 20px rgba(0,0,0,0.75); 15 | -moz-box-shadow: 0px 0px 20px rgba(0,0,0,0.75); 16 | /*-webkit-transition:all 0.5s;*/ 17 | overflow: hidden; 18 | } 19 | 20 | /*---TOP BAR---*/ 21 | #terminal-toolbar{ 22 | width: 100%; 23 | height: 25px; 24 | background: gray; 25 | border-radius: 5px 5px 0 0; 26 | 27 | background: #cfcfcf; /* Old browsers */ 28 | background: -moz-linear-gradient(top, #2f2e2b 0%, #3c3b37 100%); /* FF3.6+ */ 29 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#2f2e2b), color-stop(100%,#3c3b37)); /* Chrome,Safari4+ */ 30 | background: -webkit-linear-gradient(top, #2f2e2b 0%,#3c3b37 100%); /* Chrome10+,Safari5.1+ */ 31 | background: -o-linear-gradient(top, #2f2e2b 0%,#3c3b37 100%); /* Opera 11.10+ */ 32 | background: -ms-linear-gradient(top, #2f2e2b 0%,#3c3b37 100%); /* IE10+ */ 33 | background: linear-gradient(top, #2f2e2b 0%,#3c3b37 100%); /* W3C */ 34 | 35 | -webkit-box-shadow: 0px 1px 0px rgba(255,255,255,0.5) inset,0px 1px 0px #515151; 36 | -moz-box-shadow: 0px 1px 0px rgba(255,255,255,0.5) inset,0px 1px 0px #515151; 37 | box-shadow: 0px 1px 0px rgba(255,255,255,0.5) inset,0px 1px 0px #515151; 38 | } 39 | 40 | /*--TERMINAL BUTTONS--*/ 41 | #terminal-toolbar #terminal-buttons{ 42 | float: right; 43 | position: relative; 44 | top: 4px; 45 | right: 10px; 46 | } 47 | 48 | .terminal-button{ 49 | float: right; 50 | width: 14px; 51 | height: 14px; 52 | border-radius: 14px; 53 | -webkit-box-shadow: 0px 1px 0px rgba(255,255,255,0.5),0px 0px 3px #000 inset; 54 | -moz-box-shadow: 0px 1px 0px rgba(255,255,255,0.5),0px 0px 3px #000 inset; 55 | box-shadow: 0px 1px 0px rgba(255,255,255,0.5),0px 0px 3px #000 inset; 56 | overflow: hidden; 57 | } 58 | 59 | #terminal-buttons:hover .glyph{ 60 | opacity: 1; 61 | cursor: default; 62 | } 63 | 64 | /*--CLOSE BUTTON--*/ 65 | .terminal-close{ 66 | background: #f41b16; /* Old browsers */ 67 | margin: 0px 0px; 68 | position: relative; 69 | right: 0px; 70 | } 71 | 72 | .terminal-close-icon{ 73 | position: relative; 74 | font-size: 8px; 75 | font-weight: bold; 76 | color: #333; 77 | font-family: 'Cantarell', sans-serif; 78 | margin: 2px 0 0 4px; 79 | } 80 | 81 | /*-----TITLE TEXT-----*/ 82 | #terminal-title{ 83 | float: left; 84 | position: relative; 85 | top: 6px; 86 | width: 40%; 87 | left: 40%; 88 | font-family: 'Cantarell', sans-serif; 89 | font-size: 14px; 90 | font-weight: bold; 91 | color: #d5dfdf; 92 | line-height: 14px; 93 | } 94 | 95 | /*--TERMINAL BODY--*/ 96 | #terminal-body { 97 | font-family: monospace; line-height: 1em; 98 | font-size: 11px; 99 | float: left; 100 | width: 100%; 101 | min-height: 30px; 102 | background-color: #000; 103 | padding: 10px; 104 | line-height: 1.5em; 105 | } 106 | 107 | 108 | #terminal-body p { color: gray!important; } 109 | 110 | #terminal-body p::-moz-selection { background: #0b209e; } 111 | 112 | #terminal-body root { color: red!important; } 113 | 114 | #terminal-body user { color: lime!important; } 115 | 116 | #terminal-body p { 117 | margin-top: 5px; 118 | margin-bottom: 5px; 119 | } 120 | 121 | /*---BLINK EFFECT---*/ 122 | 123 | @keyframes blink 124 | { 125 | 0% { background:rgba(99,222,0,100); } 126 | 100% { background:rgba(99,222,0,0); } 127 | } 128 | 129 | @-webkit-keyframes blink { 130 | 0% { background:rgba(99,222,0,100); } 131 | 100% { background:rgba(99,222,0,0); } 132 | } 133 | @-moz-keyframes blink { 134 | 0% { background:rgba(99,222,0,100); } 135 | 100% { background:rgba(99,222,0,0); } 136 | } 137 | -------------------------------------------------------------------------------- /demo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |

CSSTerm Setup

12 | Include the jquery library, the cssterm css, and cssterm javascript into your existing webpages header, etc 13 | 14 |

15 | 16 | 25 | 26 |

CSSTerm Example

27 | 28 |

Full terminal window

29 | 30 | Use the following HTML to draw a full terminal window, utilizing the options below: 31 | 32 |

33 | 34 | 61 | 62 |

63 | 64 | OUTPUT: 65 | 66 |
67 | $ uname -a 68 | Linux ThinkPad-X230.localdomain 3.9.6-301.fc19.x86_64 #1 SMP Mon Jun 17 14:26:26 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux 69 | 70 | # dmesg | grep sd 71 | [135587.413741] sd 27:0:0:0: Attached scsi generic sg1 type 0 72 | [135587.416697] sd 27:0:0:0: [sdb] 2007040 512-byte logical blocks: (1.02 GB/980 MiB) 73 | [135587.418130] sd 27:0:0:0: [sdb] Write Protect is off 74 | [135587.418140] sd 27:0:0:0: [sdb] Mode Sense: 03 00 00 00 75 | [135587.418944] sd 27:0:0:0: [sdb] No Caching mode page present 76 | [135587.418947] sd 27:0:0:0: [sdb] Assuming drive cache: write through 77 | [135587.423205] sd 27:0:0:0: [sdb] No Caching mode page present 78 | [135587.423211] sd 27:0:0:0: [sdb] Assuming drive cache: write through 79 | [135587.424119] sdb: sdb1 sdb2 80 | [135587.428088] sd 27:0:0:0: [sdb] No Caching mode page present 81 | [135587.428094] sd 27:0:0:0: [sdb] Assuming drive cache: write through 82 | [135587.428098] sd 27:0:0:0: [sdb] Attached SCSI removable disk 83 | [135588.336077] SELinux: initialized (dev sdb1, type iso9660), uses genfs_contexts 84 | 85 | # mkfs.ext4 /dev/sdb1 86 | mke2fs 1.41.12 (17-May-2010) 87 | Filesystem label= 88 | OS type: Linux 89 | Block size=4096 (log=2) 90 | Fragment size=4096 (log=2) 91 | Stride=0 blocks, Stripe width=0 blocks 92 | 245280 inodes, 979456 blocks 93 | 48972 blocks (5.00%) reserved for the super user 94 | First data block=0 95 | Maximum filesystem blocks=1006632960 96 | 30 block groups 97 | 32768 blocks per group, 32768 fragments per group 98 | 8176 inodes per group 99 | Superblock backups stored on blocks: 100 | 32768, 98304, 163840, 229376, 294912, 819200, 884736 101 | 102 | Writing inode tables: done 103 | Creating journal (16384 blocks): done 104 | Writing superblocks and filesystem accounting information: done 105 | 106 | This filesystem will be automatically checked every 20 mounts or 107 | 180 days, whichever comes first. Use tune2fs -c or -i to override. 108 |
109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nstephens/cssterm/31b969451db336332b7db5c55b3abf9f471f3301/demo.png -------------------------------------------------------------------------------- /scripts/cssterm.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | 3 | // Better performance in replacing js in any browsers. http://jsperf.com/encode-html-entities 4 | if($.browser.name != "chrome") { 5 | var tagsToReplace = { 6 | '&': '&', 7 | '<': '<', 8 | '>': '>', 9 | ' ': ' ', 10 | '#': '[root@localhost]# ', 11 | '$': '[user@localhost]$ ' 12 | }; 13 | function replaceTag(tag) { 14 | return tagsToReplace[tag] || tag; 15 | } 16 | function htmlEscape(str) { 17 | return str.replace(/[&<> ]/g, replaceTag); 18 | } 19 | function userReplace(str) { 20 | return str.replace(/^[#$]/gi, replaceTag); 21 | } 22 | } else { 23 | function htmlEscape(str) { 24 | return str.replace(/&/g, '&').replace(//g, '>').replace(/ /g, ' '); 25 | } 26 | function userReplace(str) { 27 | return str.replace(/^#/gi, '[root@localhost]# ').replace(/^\$/gi, '[user@localhost]$ '); 28 | } 29 | } 30 | 31 | // the html that will be inserted to replace the shortened code 32 | // the terminal bar and body before the text is placed 33 | var termTop = '\ 34 |
\ 35 |
\ 36 |
\ 37 |
\ 38 |
\ 39 |
\ 40 |
\ 41 |
X
\ 42 |
\ 43 |
\ 44 |
\ 45 | user@localhost:~ \ 46 |
\ 47 |
\ 48 |
\ 49 |

\ 50 | '; 51 | 52 | // closes the html that has been inserted, ends the terminal display 53 | var termBot = '\ 54 |

\ 55 |
\ 56 |
\ 57 | '; 58 | 59 | // tell jQuery to search for each instance of the shortened code 60 | $(".cssterm").each(function() { 61 | var myContent = $(this).text(); 62 | var arrayContent = myContent.split('\n'); 63 | var newString = ""; 64 | jQuery.each(arrayContent, function() { 65 | // make sure there's text to avoid blank spaces 66 | if (this.length != 0) { 67 | // is string a root command 68 | if (this.charAt(0) == "#" || this.charAt(0) == "$") { 69 | newString += userReplace(this) + "
\n"; 70 | } else { 71 | newString += htmlEscape(this) + "
\n"; 72 | } 73 | } 74 | }); 75 | $(this).replaceWith( termTop + newString + termBot ); 76 | }); 77 | }); 78 | --------------------------------------------------------------------------------