Показать сообщение отдельно
  #18 (permalink)  
Старый 15.12.2017, 23:47
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,791

В результате моего поверхностного изучения ES6 родилось это (Автору вряд ли подойдет, но смысл схож):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>CLI</title>
<style>
	body{
		background:#333;
		color:#FFF;
		font-size:16px;
		line-height:20px;
	}
	.command-line{
		position:relative;
		padding-left:50px;
	}
	.command-line input,.command-line input:focus,#console{
		width:100%;
		color:inherit;
		font-size:inherit;
		font-family:inherit;
		background:transparent;
		border:none;
		outline:none;
		cursor:default;
	}
	.command-line:before{
		content:'[root]#';
		position:absolute;
		left:0;
	}
	#console{
		display:block;
		padding:0;
		margin:0;
	}
	.error{
		color:red;
	}
</style>
<script type="text/javascript">
	var INPUT,
		CONSOLE,
		__history=[],
		__history_pos=0;

	document.addEventListener('DOMContentLoaded',function(){
		var classes=['PhoneBook'],
			functions=['clear'];
		
		INPUT=document.getElementById('command-line');
		CONSOLE=document.getElementById('console');
			
		if(!INPUT || !CONSOLE)
			throw new Error('Missing one or more required HTMLElements');
		
		INPUT.addEventListener('blur',()=>INPUT.focus());
		
		INPUT.addEventListener('keydown',(e)=>{
			var keyCode=e.keyCode||e.charCode,
				offset=__history.length-__history_pos-1+2*(keyCode==40),
				val=__history[offset];
			
			if([38,40].indexOf(keyCode)<0)
				return;
			
			e.preventDefault();
			if(offset<0)
				return;
			else if(!val)
				val='';
			
			INPUT.value=val;	
			__history_pos=val?__history.length-offset:0;
		});
		
		INPUT.parentNode.addEventListener('submit',(e)=>{
			e.preventDefault();
			
			var command=INPUT.value;
			
			__history.push(command);
			__history_pos=0;
			
			CONSOLE.innerHTML+=command+'\n';
			INPUT.value='';
			
			command=command.trim().split(' ').map(i=>i.trim()).filter(i=>!!i.length);
			if(!command.length)
				return;
			
			var containers=[classes,functions],
				find_function;
				
			if(find_function=command.length==1)
				containers=containers.reverse();
			
			var name=command.shift(),
				index;
			
			for(var i in containers){
				if(!containers.hasOwnProperty(i) || (index=containers[i].indexOf(name))<0)
					continue;
				
				try{
					var res;
					if(i==0 && find_function)
						res=window[containers[i][index]](...command);
					else{
						var _class=eval(`new ${containers[i][index]}()`),
							method=command.shift();
						
						if(!method)
							break;
						
						if(typeof _class[method]!='function')
							throw new Error(`Method «${method}» not found in class «${containers[i][index]}»`);
						
						res=_class[method](...command);
					};
					
					if(typeof res=='string')
						CONSOLE.innerHTML+=res+'\n';
					
				}catch(e){
					CONSOLE.innerHTML+=`<span class="error">${e.message}</span>`+'\n';
				};
					
				break;
			};
		});
	});

	function clear(){
		CONSOLE.innerHTML='Cleared\n';
	}

	var __PhoneBook_pseudo_db={};
	class PhoneBook{
		constructor(){
			this._list=__PhoneBook_pseudo_db;
		}
		
		get __list(){
			if(!(this instanceof PhoneBook))
				throw new Error('Illegal invocation');
				
			return this._list;
		}
		
		set __list(list){
			if(!(this instanceof PhoneBook))
				throw new Error('Illegal invocation');
			
			this._list=list;
			
			return this;
		}
		
		show(){
			var row_sep='---------------------\n',
				result='Name\t\tPhone(s)\n'+row_sep;
				
			for(var name in this._list)
				result+=`${name}\t\t${this._list[name].join(', ')}\n`+row_sep;
				
			return result;
		}
		
		add(...args){
			var name=args.shift();		
			this._list[name]=(this._list[name]||[]).concat(...args);
			
			return 'Added';
		}
		
		remove(...args){
			for(var name of args)
				delete this._list[name];
				
			return 'Removed';
		}
		
		edit(...args){
			this._list[args.shift()]=args;
			
			return 'Edited';
		}
		
		clear(){
			this._list={};
		
			return 'Cleared';
		}
	};
</script>
</head>
<body>
	<pre id="console"></pre>
	<div class="command-line">
		<form><input id="command-line" type="text" autofocus autocomplete="off"/></form>
	</div>
</body>
</html>

Последний раз редактировалось Nexus, 15.12.2017 в 23:51.
Ответить с цитированием