asciimaker

- draw ascii art straight from your web browser
git clone git://git.acid.vegas/asciimaker.git
Log | Files | Refs | Archive

index.html (20181B)

      1 <html>
      2 	<head>
      3 		<title>ASCII Maker</title>
      4 		<style>
      5 			.cell{width:8px;height:16px;cursor:default;font-size:10pt;font-weight:700;font-family:Courier New}
      6 			.noDrag{-moz-user-select:none}
      7 			#canvas,#picker{margin:auto}
      8 			#drafts{position:absolute;top:5px;left:5px;font-family:Verdana;font-size:8pt}
      9 			#textBuffer{position:absolute;width:1px;height:1px}
     10 		</style>
     11 		<script type="text/javascript">
     12 			var halt = unescape('%0F');
     13 			var code = unescape('%03');
     14 			var brushColour = 4;
     15 			var mode = 0, isDragging = 0, canvasWidth = 0, canvasHeight = 0, selected = 0, curKey = 0, tool = 0;
     16 			var palette = new Array('FFFFFF', '000000', '00007F', '009300', 'FF0000', '7F0000', '9C009C', 'FC7F00', 'FFFF00', '00FC00', '009393', '00FFFF', '0000FC', 'FF00FF', '7F7F7F', 'D2D2D2');
     17 			var drafts = new Array();
     18 			var undo = new Array();
     19 
     20 			function generateCanvas(width, height) {
     21 				canvasWidth = width;
     22 				canvasHeight = height;
     23 				document.getElementById('canvas').innerHTML = '';
     24 				var tableGrid = document.createElement("table");
     25 				tableGrid.setAttribute('cellpadding', '0');
     26 				tableGrid.setAttribute('cellspacing', '0');
     27 				tableGrid.setAttribute('onmousedown', 'toggleDragging(1);');
     28 				tableGrid.setAttribute('onmouseup', 'toggleDragging(0);');
     29 				tableGrid.setAttribute('background', 'data/checkered.png');
     30 				for (var y = 0; y < height; y++) {
     31 					var currentLine = document.createElement("tr");
     32 					for (var x = 0; x < width; x++) {
     33 						var currentCell = document.createElement("td");
     34 						currentCell.setAttribute('class', 'cell');
     35 						currentCell.innerHTML = ' ';
     36 						currentCell.setAttribute('onmousemove', 'fillCell(' + (width * y + x) + ');');
     37 						currentCell.setAttribute('onmousedown', 'isDragging=1;fillCell(' + (width * y + x) + ');');
     38 						currentLine.appendChild(currentCell);
     39 					}
     40 					tableGrid.appendChild(currentLine);
     41 				}
     42 				document.getElementById('canvas').style.width = x * 8 + 'px';
     43 				document.getElementById('canvas').appendChild(tableGrid);
     44 			}
     45 
     46 			function generatePalette() {
     47 				var paletteGrid = document.createElement("table");
     48 				paletteGrid.setAttribute('cellspacing', '2');
     49 				var paletteLine = document.createElement("tr");
     50 				for (i = 0; i < 16; i++) {
     51 					var currentPalette = document.createElement('td');
     52 					currentPalette.setAttribute('style', 'width: 20px; height: 20px; background-color: #' + palette[i] + ';');
     53 					currentPalette.setAttribute('onclick', 'setColour(' + i + ');');
     54 					paletteLine.appendChild(currentPalette);
     55 				}
     56 				paletteGrid.appendChild(paletteLine);
     57 				document.getElementById('picker').style.width = '360px';
     58 				document.getElementById('picker').appendChild(paletteGrid);
     59 			}
     60 
     61 			function setColour(i) {
     62 				brushColour = i;
     63 			}
     64 
     65 			function fillCell(index) {
     66 				if (tool == 0) {
     67 					if (isDragging == 1 && mode == 0) {
     68 						if (curKey != 17 && curKey != 18) setBackgroundColour(index);
     69 						else remBackgroundColour(index);
     70 					} else if (isDragging == 1 && mode == 1) {
     71 						if (curKey == 17 || curKey == 18) {
     72 							setLetter(index, '');
     73 							remColour(index);
     74 						}
     75 						document.getElementById('textBuffer').focus();
     76 						remCursor(selected);
     77 						selected = index;
     78 						setCursor(selected);
     79 						if (document.getElementsByTagName('td')[selected].innerHTML != ' ' && document.getElementsByTagName('td')[selected].innerHTML != '') document.getElementsByTagName('td')[selected].style.color = palette[brushColour];
     80 					}
     81 				} else {
     82 					fillArea(index);
     83 				}
     84 			}
     85 
     86 			function fillArea(index) {
     87 				var newSeeds = new Array();
     88 				var x = index % canvasWidth;
     89 				var y = (index - x) / canvasWidth;
     90 				var c = getCellColour(x, y);
     91 				var x1 = getLineColourLimits(x, y, 'left');
     92 				var x2 = getLineColourLimits(x, y, 'right');
     93 				if (isDragging == 1) {
     94 					for (var m = 0; m < 2; m++) {
     95 						y = (index - x) / canvasWidth + m;
     96 						while (y >= 0 && y <= canvasHeight) {
     97 							if (getCellColour(x, y) != c) break;
     98 							var x1 = getLineColourLimits(x, y, 'left');
     99 							var x2 = getLineColourLimits(x, y, 'right');
    100 							for (var i = x1; i <= x2; i++)
    101 								if (curKey != 17 && curKey != 18) setBackgroundColour((canvasWidth * y) + i);
    102 								else remBackgroundColour((canvasWidth * y) + i);
    103 							if (m == 0) y--;
    104 							else y++;
    105 						}
    106 					}
    107 				}
    108 			}
    109 
    110 			function getLineColourLimits(x, y, end) {
    111 				var boundary = x;
    112 				var currentColour;
    113 				var targetColour = getCellColour(x, y);
    114 				var i = x;
    115 				while (i >= 0 && i < canvasWidth) {
    116 					currentColour = getCellColour(i, y);
    117 					if (currentColour == targetColour) boundary = i;
    118 					else break;
    119 					if (end == 'left') i--;
    120 					else i++;
    121 				}
    122 				return boundary;
    123 			}
    124 
    125 			function toggleMode(newMode) {
    126 				if (newMode != undefined) mode = newMode;
    127 				if (mode == 1) {
    128 					remCursor(selected);
    129 					document.getElementById('typeButton').innerHTML = 'Type';
    130 				} else {
    131 					toggleTool(1);
    132 					setCursor(selected);
    133 					document.getElementById('textBuffer').focus();
    134 					document.getElementById('typeButton').innerHTML = 'Draw';
    135 				}
    136 				mode = (mode - 1) * -1
    137 			}
    138 
    139 			function toggleTool(newTool) {
    140 				toggleMode(1);
    141 				if (newTool != undefined) tool = newTool;
    142 				if (tool == 1) document.getElementById('toolButton').innerHTML = 'Fill';
    143 				else document.getElementById('toolButton').innerHTML = 'Brush';
    144 				tool = (tool - 1) * -1
    145 			}
    146 
    147 			function toggleDragging(bool) {
    148 				isDragging = bool;
    149 			}
    150 
    151 			function padColour(colourCode, letter) {
    152 				if (colourCode < 10 && isNaN(parseFloat(letter)) == false) {
    153 					return '0' + colourCode;
    154 				}
    155 				return colourCode;
    156 			}
    157 
    158 			function renderArt() {
    159 				var line, output = ''
    160 				var lastColour, lastFontColour, currentColour, currentFontColour, breakout;
    161 				for (var y = 0; y < canvasHeight; y++) {
    162 					line = '';
    163 					for (var x = 0; x < canvasWidth; x++) {
    164 						lastColour = getCellColour(x, y);
    165 						lastFontColour = getFontColour(x, y);
    166 						if (lastFontColour >= 0 && lastColour >= 0) {
    167 							line += code + lastFontColour + ',' + padColour(lastColour, getCellLetter(x, y));
    168 						} else if (lastFontColour >= 0 && lastColour < 0) {
    169 							if (x != 0) line += halt;
    170 							line += code + padColour(lastFontColour, getCellLetter(x, y));
    171 						} else if (lastFontColour < 0 && lastColour >= 0) {
    172 							line += code + lastColour + ',' + padColour(lastColour, getCellLetter(x, y));
    173 						} else {
    174 							line += getCellLetter(x, y);
    175 						}
    176 						if (lastFontColour >= 0 || lastColour >= 0) {
    177 							breakout = 0;
    178 							for (var z = x; z < canvasWidth; z++) {
    179 								currentColour = getCellColour(z, y);
    180 								currentFontColour = getFontColour(z, y);
    181 								if (currentFontColour == lastFontColour && currentColour == lastColour) {
    182 									line += getCellLetter(z, y);
    183 								} else {
    184 									x = z - 1;
    185 									breakout = 1;
    186 									break;
    187 								}
    188 							}
    189 							line += code;
    190 							if (breakout == 0) x = canvasWidth;
    191 						}
    192 					}
    193 					output += endtrim(line, ' ') + " \n";
    194 				}
    195 				var remove = new RegExp(code + code, 'gi');
    196 				output = output.replace(remove, code);
    197 				output = output.replace(/&lt;/g, '<');
    198 				output = output.replace(/&gt;/g, '>');
    199 				document.getElementById('load').value = endtrim(output);
    200 			}
    201 
    202 			function previewArt() {
    203 				renderArt();
    204 				document.getElementById('preview').innerHTML = '';
    205 				var tempForm = document.createElement('form');
    206 				tempForm.setAttribute('method', 'POST');
    207 				tempForm.setAttribute('action', '/preview/preview.php');
    208 				tempForm.setAttribute('target', '_blank');
    209 				var tempField = document.createElement('input');
    210 				tempField.setAttribute('name', 'ascii');
    211 				tempField.setAttribute('type', 'hidden');
    212 				tempField.value = escape(document.getElementById('load').value);
    213 				var rawField = document.createElement('input');
    214 				rawField.setAttribute('name', 'raw');
    215 				rawField.setAttribute('type', 'hidden');
    216 				rawField.value = 1;
    217 				tempForm.appendChild(tempField);
    218 				tempForm.appendChild(rawField);
    219 				document.getElementById('preview').appendChild(tempForm);
    220 				document.forms[0].submit();
    221 			}
    222 
    223 			function resizeArt() {
    224 				var x = parseFloat(prompt('wqat width? (in characters)', canvasWidth));
    225 				var y = parseFloat(prompt('wqat height? (in characters)', canvasHeight));
    226 				renderArt();
    227 				generateCanvas(x, y);
    228 				drawImage();
    229 			}
    230 
    231 			function loadArt() {
    232 				var dimensions = getAsciiWidth();
    233 				generateCanvas(dimensions[0], dimensions[1]);
    234 				drawImage();
    235 			}
    236 
    237 			function drawImage() {
    238 				var g_width = 0;
    239 				var lines = endtrim(document.getElementById('load').value, "\n");
    240 				lines = lines.split("\n");
    241 				for (var y in lines) {
    242 					var index = y * canvasWidth;
    243 					var last_foreground = 16;
    244 					var last_background = 16;
    245 					var blocks = lines[y].split(code);
    246 					for (var b in blocks) {
    247 						if (blocks[b].length > 0) {
    248 							var colours = getColoursFromLine(blocks[b], blocks.length, last_foreground, last_background);
    249 							last_background = colours[1];
    250 							for (var i = 0; i < colours[3].length; i++) {
    251 								if (colours[3].charCodeAt(i) == 15) {
    252 									last_background = 16;
    253 								} else if (colours[3].charCodeAt(i) > 31 && colours[3].charCodeAt(i) < 127) {
    254 									document.getElementsByTagName('td')[index].style.color = palette[parseFloat(colours[0])];
    255 									if (colours[1] < 16) document.getElementsByTagName('td')[index].style.backgroundColor = palette[parseFloat(colours[1])];
    256 									document.getElementsByTagName('td')[index].innerHTML = colours[3].charAt(i);
    257 									index++;
    258 								}
    259 							}
    260 						}
    261 					}
    262 				}
    263 			}
    264 
    265 			function endtrim(str, chars) {
    266 				chars = chars || "\\s";
    267 				return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
    268 			}
    269 
    270 			function getColoursFromLine(line, block_count, last_foreground, last_background) {
    271 				var colours = new Array();
    272 				if (block_count > 1) {
    273 					var chunks = line.split(',', 2);
    274 					for (var c in chunks) {
    275 						var current = '';
    276 						for (var i = 0; i < 2; i++) {
    277 							if (isNaN(parseFloat(chunks[c].charAt(i))) == false) current += chunks[c].charAt(i);
    278 						}
    279 						if (isNaN(parseFloat(current)) == false) colours[colours.length] = current;
    280 					}
    281 				}
    282 				colours[3] = line.substr(colours.join(',').length);
    283 				if (typeof(colours[0]) != 'undefined' && typeof(colours[1]) == 'undefined') colours[1] = last_background;
    284 				if (typeof(colours[0]) == 'undefined') colours[0] = last_foreground;
    285 				return colours;
    286 			}
    287 
    288 			function getAsciiWidth() {
    289 				var g_width = 0;
    290 				var lines = endtrim(document.getElementById('load').value, "\n");
    291 				lines = lines.split("\n");
    292 				for (var y in lines) {
    293 					var l_width = 0;
    294 					var blocks = lines[y].split(code);
    295 					for (var b in blocks) {
    296 						if (blocks[b].length > 0) {
    297 							var colours = getColoursFromLine(blocks[b], blocks.length);
    298 							for (var i = 0; i < colours[3].length; i++) {
    299 								if (colours[3].charCodeAt(i) > 31 && colours[3].charCodeAt(i) < 127) l_width++;
    300 							}
    301 						}
    302 					}
    303 					if (l_width > g_width) g_width = l_width;
    304 				}
    305 				return new Array(g_width, lines.length);
    306 			}
    307 
    308 			function getCellColour(x, y) {
    309 				var colour = document.getElementsByTagName('td')[(canvasWidth * y + x)].style.backgroundColor;
    310 				return ircFromHex(rgbConvert(colour));
    311 			}
    312 
    313 			function getFontColour(x, y) {
    314 				var colour = document.getElementsByTagName('td')[(canvasWidth * y + x)].style.color;
    315 				return ircFromHex(rgbConvert(colour));
    316 			}
    317 
    318 			function getCellLetter(x, y) {
    319 				var letter = document.getElementsByTagName('td')[(canvasWidth * y + x)].innerHTML;
    320 				if (letter == '') letter = ' ';
    321 				return letter;
    322 			}
    323 
    324 			function rgbConvert(str) {
    325 				if (navigator.userAgent.match('Opera') == null) {
    326 					str = str.replace(/rgb\(|\)/g, "").split(",");
    327 					str[0] = parseInt(str[0], 10).toString(16).toUpperCase();
    328 					str[1] = parseInt(str[1], 10).toString(16).toUpperCase();
    329 					str[2] = parseInt(str[2], 10).toString(16).toUpperCase();
    330 					str[0] = (str[0].length == 1) ? '0' + str[0] : str[0];
    331 					str[1] = (str[1].length == 1) ? '0' + str[1] : str[1];
    332 					str[2] = (str[2].length == 1) ? '0' + str[2] : str[2];
    333 					return str.join("");
    334 				} else {
    335 					return str.replace(/#/g, '').toUpperCase();
    336 				}
    337 			}
    338 
    339 			function ircFromHex(hex) {
    340 				for (var i = 0; i < 16; i++) {
    341 					if (palette[i] == hex) return i;
    342 				}
    343 				return -1;
    344 			}
    345 			document.onmousemove = function moveBuffer(e) {
    346 				var y = e.clientY + document.body.scrollTop + 5;
    347 				if (y < (window.innerHeight + window.scrollMaxY - 30)) {
    348 					document.getElementById('textBuffer').style.left = '0px';
    349 					document.getElementById('textBuffer').style.top = y + 'px';
    350 				}
    351 			}
    352 			document.onkeydown = function setKey(e) {
    353 				var code;
    354 				if (window.event) code = window.event.keyCode;
    355 				else if (e) code = e.which;
    356 				curKey = code;
    357 				if (mode == 0) {
    358 					if (code == 38) // up
    359 						shiftArt('up');
    360 					else if (code == 40) // down
    361 						shiftArt('down');
    362 					else if (code == 37) // left
    363 						shiftArt('left');
    364 					else if (code == 39) // right
    365 						shiftArt('right');
    366 				}
    367 				if (curKey == 27) loadLastUndo();
    368 			}
    369 			document.onkeyup = function handleKey(e) {
    370 				var code;
    371 				if (window.event) code = window.event.keyCode;
    372 				else if (e) code = e.which;
    373 				curKey = 0;
    374 				if (mode == 1) {
    375 					if (code == 8) {
    376 						remCursor(selected);
    377 						selected--;
    378 						setCursor(selected);
    379 						setLetter(selected, '');
    380 						remColour(selected);
    381 					} else if (code == 38 && (selected - canvasWidth) >= 0) // up
    382 						moveCursor(selected - canvasWidth);
    383 					else if (code == 40 && (selected + canvasWidth) < canvasWidth * canvasHeight) // down
    384 						moveCursor(selected + canvasWidth);
    385 					else if (code == 37 && (selected - 1) >= 0) // left
    386 						moveCursor(selected - 1);
    387 					else if (code == 39 && (selected + 1) < canvasWidth * canvasHeight) // right
    388 						moveCursor(selected + 1);
    389 					else {
    390 						var data = document.getElementById('textBuffer').value;
    391 						for (var i = 0; i < data.length; i++) {
    392 							remCursor(selected);
    393 							setCursor(selected + 1);
    394 							setLetter(selected, data.charAt(i));
    395 							selected++;
    396 						}
    397 						document.getElementById('textBuffer').value = '';
    398 					}
    399 				}
    400 			}
    401 
    402 			function setCursor(index) {
    403 				document.getElementsByTagName('td')[index].style.backgroundImage = 'url(cursor.png)';
    404 			}
    405 
    406 			function remCursor(index) {
    407 				document.getElementsByTagName('td')[index].style.backgroundImage = '';
    408 			}
    409 
    410 			function moveCursor(index) {
    411 				remCursor(selected);
    412 				selected = index;
    413 				setCursor(selected);
    414 			}
    415 
    416 			function setLetter(index, data) {
    417 				document.getElementsByTagName('td')[index].style.color = palette[brushColour];
    418 				document.getElementsByTagName('td')[index].innerHTML = data;
    419 			}
    420 
    421 			function remColour(index) {
    422 				document.getElementsByTagName('td')[index].style.color = '';
    423 			}
    424 
    425 			function setBackgroundColour(index) {
    426 				if (rgbConvert(document.getElementsByTagName('td')[index].style.backgroundColor) != palette[brushColour]) {
    427 					saveStateUndo(index);
    428 					document.getElementsByTagName('td')[index].style.backgroundColor = palette[brushColour];
    429 				}
    430 			}
    431 
    432 			function remBackgroundColour(index) {
    433 				if (document.getElementsByTagName('td')[index].style.backgroundColor != '') {
    434 					saveStateUndo(index);
    435 					document.getElementsByTagName('td')[index].style.backgroundColor = '';
    436 				}
    437 			}
    438 
    439 			function saveStateUndo(index) {
    440 				if (undo.length > 50000) undo.splice(0, 1);
    441 				var i = undo.length;
    442 				undo[i] = new Array();
    443 				undo[i][0] = index;
    444 				undo[i][1] = document.getElementsByTagName('td')[index].style.color;
    445 				undo[i][2] = document.getElementsByTagName('td')[index].style.backgroundColor;
    446 				undo[i][3] = document.getElementsByTagName('td')[index].innerHTML;
    447 				document.getElementById('undoButton').disabled = 0;
    448 			}
    449 
    450 			function loadLastUndo() {
    451 				if (undo.length > 0) {
    452 					var currentUndo = undo[undo.length - 1];
    453 					document.getElementsByTagName('td')[currentUndo[0]].style.color = currentUndo[1];
    454 					document.getElementsByTagName('td')[currentUndo[0]].style.backgroundColor = currentUndo[2];
    455 					document.getElementsByTagName('td')[currentUndo[0]].innerHTML = currentUndo[3];
    456 					undo.splice(undo.length - 1, 1);
    457 					if (undo.length <= 0) document.getElementById('undoButton').disabled = 1;
    458 				} else {
    459 					document.getElementById('undoButton').disabled = 1;
    460 				}
    461 			}
    462 
    463 			function addDraft() {
    464 				var d = new Date();
    465 				var i = drafts.length;
    466 				renderArt();
    467 				drafts[i] = new Array();
    468 				drafts[i][0] = document.getElementById('load').value;
    469 				drafts[i][1] = d.toUTCString();
    470 				drawDrafts();
    471 			}
    472 
    473 			function drawDrafts() {
    474 				document.getElementById('drafts').innerHTML = '';
    475 				for (var i in drafts) document.getElementById('drafts').innerHTML += '#' + i + ' <a style=\'cursor: pointer;\' onclick=\'loadDraft(' + i + ');\'>' + drafts[i][1] + "</a><br />\n";
    476 			}
    477 
    478 			function loadDraft(index) {
    479 				document.getElementById('load').value = drafts[index][0];
    480 				loadArt();
    481 			}
    482 
    483 			function copyArt() {
    484 				copy(document.getElementById('load'));
    485 			}
    486 
    487 			function shiftArt(direction) {
    488 				var newLoc;
    489 				if (direction == 'down' || direction == 'right') var i = (canvasWidth * canvasHeight) - 1;
    490 				else var i = 0;
    491 				while (i >= 0 && i < (canvasWidth * canvasHeight)) {
    492 					if (direction == 'up' || direction == 'down') newLoc = i - canvasWidth;
    493 					else if (direction == 'left' || (direction == 'right')) newLoc = i - 1;
    494 					var newCell = document.getElementsByTagName('td')[newLoc];
    495 					var oldCell = document.getElementsByTagName('td')[i];
    496 					if (newLoc >= 0 && newLoc < (canvasWidth * canvasHeight)) {
    497 						if (direction == 'up' || direction == 'left') {
    498 							newCell.style.color = oldCell.style.color;
    499 							newCell.style.backgroundColor = oldCell.style.backgroundColor;
    500 							newCell.innerHTML = oldCell.innerHTML;
    501 						} else if (direction == 'down' || direction == 'right') {
    502 							oldCell.style.color = newCell.style.color;
    503 							oldCell.style.backgroundColor = newCell.style.backgroundColor;
    504 							oldCell.innerHTML = newCell.innerHTML;
    505 						}
    506 					}
    507 					if (direction == 'up' || direction == 'left') i++;
    508 					else if (direction == 'down' || direction == 'right') i--;
    509 				}
    510 			}
    511 
    512 			function copy(inElement) {
    513 				if (inElement.createTextRange) {
    514 					var range = inElement.createTextRange();
    515 					if (range && BodyLoaded == 1) range.execCommand('Copy');
    516 				} else {
    517 					var flashcopier = 'flashcopier';
    518 					if (!document.getElementById(flashcopier)) {
    519 						var divholder = document.createElement('div');
    520 						divholder.id = flashcopier;
    521 						document.body.appendChild(divholder);
    522 					}
    523 					document.getElementById(flashcopier).innerHTML = '';
    524 					var divinfo = '<embed src="data/clipboard.swf" FlashVars="clipboard=' + escape(inElement.value) + '" width="0" height="0" type="application/x-shockwave-flash"></embed>';
    525 					document.getElementById(flashcopier).innerHTML = divinfo;
    526 				}
    527 			}
    528 		</script>
    529 	</head>
    530 	<body onload='generateCanvas(80,24); generatePalette();' onkeydown='if(mode == 1) document.getElementById("textBuffer").focus();'>
    531 		<center>
    532 			<b>ASCII Maker</b>
    533 			<br><small><i>(<a href="https://github.com/ircart/asciimaker">source</a>)</i></small>
    534 			<br><br>
    535 		</center>
    536 		<div class='noDrag' id='canvas'></div>
    537 		<div class='noDrag' id='picker'></div>
    538 		<div id='preview'></div>
    539 		<div class='drafts' id='drafts'></div>
    540 		<p align='center'>
    541 			<button onclick='addDraft();'>Save</button>
    542 			<button onclick='loadArt();'>Load</button>
    543 			<button onclick='generateCanvas(canvasWidth, canvasHeight);'>Clear</button>
    544 			<button onclick='renderArt();'>Render</button>
    545 			<button onclick='copyArt();'>Copy</button>
    546 			<button onclick='toggleMode();' id='typeButton'>Type</button>	
    547 			<button onclick='toggleTool();' id='toolButton'>Fill</button>
    548 			<button onclick='resizeArt();'>Resize</button>
    549 			<button onclick='loadLastUndo();' id='undoButton' DISABLED>Undo</button>
    550 			<br>
    551 			<textarea id='load' cols='30' rows='3' readonly></textarea><br />
    552 			<input type='text' id='textBuffer' onkeydown='if(mode != 1) return false;' style='opacity: 0;'><br />
    553 		</p>
    554 	</body>
    555 </html>