Преглед изворни кода

Merge pull request #561 from visuddhinanda/master

添加 term 辅助输入
visuddhinanda пре 4 година
родитељ
комит
d2f8bdf4af
7 измењених фајлова са 551 додато и 375 уклоњено
  1. 6 1
      app/article/index.php
  2. 22 4
      app/public/js/comm.js
  3. 10 10
      app/studio/js/editor.js
  4. 286 9
      app/term/note.js
  5. 76 0
      app/term/term.css
  6. 0 276
      app/term/text_compare.html
  7. 151 75
      app/widget/term_input.html

+ 6 - 1
app/article/index.php

@@ -4,7 +4,9 @@ require_once "../path.php";
 require_once "../pcdl/html_head.php";
 ?>
 <body style="margin: 0;padding: 0;" class="reader_body" >
-
+	<script>
+		var gCaseTable=<?php echo file_get_contents("../public/js/case.json"); ?>
+	</script>
 
 	<script  src="./article.js"></script>
 
@@ -58,6 +60,9 @@ require_once "../pcdl/html_head.php";
 	if(isset($_GET["par"])){
 		echo "_par=".$_GET["par"].";";
 	}
+	if(isset($_GET["para"])){
+		echo "_par=".$_GET["para"].";";
+	}
 	if(isset($_GET["start"])){
 		echo "_start=".$_GET["start"].";";
 	}

+ 22 - 4
app/public/js/comm.js

@@ -103,13 +103,31 @@ function com_getPaliReal(inStr) {
 	inStr = inStr.toLowerCase();
 	inStr = inStr.replace(/ṁ/g, "ṃ");
 	inStr = inStr.replace(/ŋ/g, "ṃ");
-	for (x in inStr) {
-		if (paliletter.indexOf(inStr[x]) != -1) {
-			output += inStr[x];
-		}
+	for (const iterator of inStr) {
+		if (paliletter.indexOf(iterator) != -1) {
+			output += iterator;
+		}		
 	}
 	return output;
 }
+function com_getPaliEn(inStr) {
+	if (typeof inStr == "undefined") {
+		return "";
+	}
+	inStr = inStr.toLowerCase();
+	inStr = inStr.replace(/ā/g, "a");
+	inStr = inStr.replace(/ī/g, "i");
+	inStr = inStr.replace(/ū/g, "u");
+	inStr = inStr.replace(/ṅ/g, "n");
+	inStr = inStr.replace(/ñ/g, "n");
+	inStr = inStr.replace(/ṇ/g, "n");
+	inStr = inStr.replace(/ṭ/g, "t");
+	inStr = inStr.replace(/ḍ/g, "d");
+	inStr = inStr.replace(/ḷ/g, "l");
+	inStr = inStr.replace(/ṃ/g, "m");
+
+	return inStr;
+}
 
 function getCookie(c_name) {
 	if (document.cookie.length > 0) {

+ 10 - 10
app/studio/js/editor.js

@@ -4285,24 +4285,24 @@ function inline_dict_parse(data) {
 }
 //添加自动格位数据到内存字典
 function inline_dict_auto_case(paliword) {
-	for (let i in gCaseTable) {
-		if (gCaseTable[i].type != ".v.") {
-			let sEnd2 = gCurrLookupWord.slice(0 - gCaseTable[i].end2.length);
-			if (sEnd2 == gCaseTable[i].end2) {
-				let wordParent = gCurrLookupWord.slice(0, 0 - gCaseTable[i].end2.length) + gCaseTable[i].end1;
+	for (const it of gCaseTable) {
+		if (it.type != ".v.") {
+			let sEnd2 = gCurrLookupWord.slice(0 - it.end2.length);
+			if (sEnd2 == it.end2) {
+				let wordParent = gCurrLookupWord.slice(0, 0 - it.end2.length) + it.end1;
 				let newWord = new Object();
 				newWord.pali = gCurrLookupWord;
-				newWord.type = gCaseTable[i].type;
-				newWord.gramma = gCaseTable[i].gramma;
+				newWord.type = it.type;
+				newWord.gramma = it.gramma;
 				newWord.parent = wordParent;
 				newWord.mean = "";
 				newWord.note = "";
-				newWord.parts = wordParent + "+[" + gCaseTable[i].end2 + "]";
+				newWord.parts = wordParent + "+[" + it.end2 + "]";
 				newWord.partmean = "";
-				newWord.confidence = gCaseTable[i].confidence;
+				newWord.confidence = it.confidence;
 				mDict[paliword].push(newWord);
 			}
-		}
+		}		
 	}
 }
 

+ 286 - 9
app/term/note.js

@@ -45,6 +45,7 @@ function note_create() {
 	term_edit_dlg_init();
 	pali_sim_dlg_init();
 	related_para_dlg_init();
+	term_get_all_pali();
 }
 function note_sent_edit_dlg_init() {
 	$("body").append(
@@ -851,7 +852,35 @@ function render_icon_button(icon_id, event, tiptitle) {
 	html += "</button>";
 	return html;
 }
+var menuFocusIndex=0;
+var term_data=["amanussa","anadhiṭṭhita","anantarāya","anissaṭṭha","aniyata","antaravāsaka"];
+var term_filterd_data=[];
+var term_input_text ;
+var term_input="";
+
+function TermRenderSentTranTextarea(text,dbId,sentId,channelId,isPr){
+	let html="";
+	html += '<div class="text_input" >';
+	html += '<div class="menu"></div>';
+	html += '<div class="textarea text_shadow"></div>';
+
+	html += "<textarea class='textarea tran_sent_textarea' onfocus=\"text_input_textarea_focuse(this)\"";
+	html += " dbid='" + dbId + "' ";
+	html += "sid='" + sentId + "' ";
+	html += "channel='" + channelId + "' ";
+	if (typeof isPr != "undefined" && isPr == true) {
+		html += ' is_pr="true" "';
+	} else {
+		html += 'is_pr="false"';
+	}
+
+	html += ">" ;
+	html += text;
+	html += "</textarea>";
 
+	html += '</div>';
+	return html;
+}
 function render_one_sent_tran_a(iterator, diff = false) {
 	let mChannel = get_channel_by_id(iterator.channal);
 
@@ -1062,16 +1091,11 @@ function render_one_sent_tran_a(iterator, diff = false) {
 
 	html += '<div class="edit">';
 	html += '<div class="input">';
-	html += "<textarea class='tran_sent_textarea' dbid='" + iterator.id + "' ";
-	html += "sid='" + sid + "' ";
-	html += "channel='" + iterator.channal + "' ";
-	if (typeof iterator.is_pr != "undefined" && iterator.is_pr == true) {
-		html += ' is_pr="true" onchange1="note_pr_save(this)"';
-	} else {
-		html += 'is_pr="false" onchange1="note_sent_save_a(this)"';
-	}
 
-	html += ">" + iterator.text + "</textarea>";
+	//输入框
+	html += TermRenderSentTranTextarea(iterator.text,iterator.id,sid,iterator.channal,iterator.is_pr);
+
+
 	html += "</div>";
 	html += '<div class="edit_tool">';
 	//html += ""
@@ -2103,3 +2127,256 @@ function setDisplay(obj) {
 function render_heading_toc() {
 	//$(":header")
 }
+
+
+//术语输入At 
+const _term_max_menu=9;
+function term_set_word_list_data(el){
+	let sid = $(el).attr("sid");
+	let asid = sid.split("-");
+	let words=new Array();
+	let tmpWords = [];
+	term_data=[];
+	for (const it of _arrData) {
+		if(it.book==asid[0] && it.para==asid[1] && it.begin==asid[2] && it.end==asid[3]){
+			let palitext = it.palitext;
+			words = palitext.split(" ");
+		}
+	}
+	console.log("word",words);
+	//查询parent
+	for (let index = 0; index < words.length; index++) {
+		words[index] = com_getPaliReal(words[index]);
+		if(words[index]!=""){
+			let parents = term_parent(words[index]);
+
+			for (const key in parents) {
+				if (parents.hasOwnProperty.call(parents, key)) {		
+					//term_data.push({word:key,en:com_getPaliEn(key),weight:weight});
+					tmpWords[key]={word:key,en:com_getPaliEn(key),weight:3,exist:0};
+				}
+			}
+		}
+	}
+	for (const iterator of arrTermAllPali) {
+		if(tmpWords.hasOwnProperty(iterator.word)){
+			tmpWords[iterator.word].weight+=1;
+			tmpWords[iterator.word].exist=1;
+		}else{
+			tmpWords[iterator.word]={word:iterator.word,en:com_getPaliEn(iterator.word),weight:1,exist:1};
+		}
+	}	
+	for (const iterator of arrMyTerm) {
+		if(tmpWords.hasOwnProperty(iterator.word)){
+			tmpWords[iterator.word].weight+=1;
+			tmpWords[iterator.word].exist=2;
+		}else{
+			tmpWords[iterator.word]={word:iterator.word,en:com_getPaliEn(iterator.word),weight:1,exist:2};
+		}
+	}
+	for (const key in tmpWords) {
+		if (tmpWords.hasOwnProperty.call(tmpWords, key)) {
+			const element = tmpWords[key];
+			term_data.push(element);
+		}
+	}
+	term_data.sort(function(a,b){
+		return b.weight-a.weight;
+	});
+
+}
+
+function text_input_textarea_focuse(el){
+	term_set_word_list_data(el);
+	term_input_text = el;
+	term_input_text.onresize = function(){
+		term_input_text.parentElement.querySelector(".text_shadow").style.height=term_input_text.clientHeight+"px";
+	}
+	term_input_text.onkeydown = function (e) {
+	
+		let menu = term_input_text.parentElement.querySelector('.menu');
+		switch (e.key) {
+			case "ArrowDown"://down arrow
+				if(menu.style.display=="block"){
+					menuFocusIndex++;
+					if(menuFocusIndex>_term_max_menu){
+						menuFocusIndex=_term_max_menu;
+					}
+					menu.innerHTML=TermAtRenderMenu({focus:menuFocusIndex});
+					return false;					
+				}
+				break;
+			case "ArrowUp"://up arrow
+				if(menu.style.display=="block"){
+					menuFocusIndex--;
+					if(menuFocusIndex<0){
+						menuFocusIndex=0;
+					}
+					menu.innerHTML=TermAtRenderMenu({focus:menuFocusIndex});
+					return false;					
+				}
+			break;
+			case "Enter":
+				if(menu.style.display=="block"){
+					term_insert(term_filterd_data[menuFocusIndex-1]);
+					return false;
+				}
+				
+				break;
+			case "Escape":
+				break;
+			default:
+				break;
+		}
+	}
+	term_input_text.onkeyup = function (e) {
+		let textHeight = term_input_text.parentElement.querySelector(".text_shadow").scrollHeight;
+		let textHeight2 = term_input_text.clientHeight;
+		if(textHeight2>textHeight){
+			textHeight=textHeight2;
+		}
+		term_input_text.style.height = textHeight+"px";
+		console.log("text height",textHeight);
+
+	let value = term_input_text.value
+	let selectionStart = term_input_text.selectionStart
+	let str1 = value.slice(0, selectionStart)
+	let str2 = value.slice(selectionStart)
+	let textNode1 = document.createTextNode(str1)
+	let textNode2 = document.createTextNode(str2)
+	let cursor = document.createElement('span')
+	cursor.innerHTML = '&nbsp;'
+	cursor.setAttribute('class','cursor')
+	let mirror = term_input_text.parentElement.querySelector('.text_shadow')
+	mirror.innerHTML = ''
+	mirror.appendChild(textNode1)
+	mirror.appendChild(cursor)
+	mirror.appendChild(textNode2)
+	let menu = term_input_text.parentElement.querySelector('.menu');	
+	if(str1.slice(-2)=="[[" ){
+		if( menu.style.display!="block"){
+			menuFocusIndex=0;
+			menu.innerHTML=TermAtRenderMenu({focus:0});
+			term_at_menu_show(cursor);
+		}
+	}else{
+		if( menu.style.display=="block"){
+			let pos1=str1.lastIndexOf("[[");
+			let pos2=str1.lastIndexOf("]]");
+			if(pos1==-1 || (pos2!=-1 || pos2>pos1)){
+				//光标前没有[[ 光标在[[]] 之后
+				term_at_menu_hide();
+			}
+		}
+	}
+
+	if(e.key=="Escape"){
+		term_at_menu_hide();
+	}
+	
+	if(menu.style.display=="block"){
+		//term_input += e.key;
+		let value = term_input_text.value
+		let selectionStart = term_input_text.selectionStart
+		let str1 = value.slice(0, selectionStart)
+		let str2 = value.slice(selectionStart)
+		let pos1=str1.lastIndexOf("[[");
+		let pos2=str1.lastIndexOf("]]");
+		if(pos1!=-1){
+			if(pos2==-1 || pos2<pos1){
+				//光标
+				term_input = str1.slice(str1.lastIndexOf("[[")+2);
+			}
+		}
+		console.log("term_input",term_input);
+		menu.innerHTML=TermAtRenderMenu({focus:menuFocusIndex});
+	}
+
+	console.log(e.key);
+	console.log(cursor.offsetLeft,cursor.offsetTop)
+}
+
+}
+function term_at_menu_show(cursor){
+	let menu = term_input_text.parentElement.querySelector('.menu');
+	menu.style.display="block";
+	menu.style.top=cursor.offsetTop+20+"px";
+	menu.style.left=cursor.offsetLeft+"px";
+	$(document).on("keyup", function (e) {
+		if(e.key=="Escape"){
+			term_at_menu_hide();
+		}
+	});
+}
+function term_at_menu_hide(){
+	let menu = term_input_text.parentElement.querySelector('.menu');
+	menu.style.display="none";
+	term_input="";
+}
+function term_insert(strTerm){
+	let value = term_input_text.value;
+	let selectionStart = term_input_text.selectionStart;
+	let str1 = value.slice(0, selectionStart)
+	let str2 = value.slice(selectionStart)
+	let pos1=str1.lastIndexOf("[[");
+	let pos2=str1.lastIndexOf("]]");
+	if(pos1!=-1){
+		//光标前有[[
+		if(pos2==-1 || pos2<pos1){
+			//光标在[[之间]]
+			str1 = str1.slice(0,str1.lastIndexOf("[[")+2);
+		}
+	}
+
+	//TODO 光标会跑到最下面
+	term_input_text.value = str1+strTerm+"]]"+str2;
+	term_at_menu_hide();
+}
+function TermAtRenderMenu(params) {
+	term_filterd_data=[];
+	let html="";
+	html +="<div class='term_at_menu_input'>"+term_input+"|</div>";
+	html +="<ul class='term_at_menu_ul'>";
+	let index=0;
+	let focusIndex = params.focus%term_data.length;
+	for (const it of term_data) {
+		if(term_input=="" || it.word.indexOf(term_input)==0 || it.en.indexOf(term_input)==0){
+			index++;
+			html +="<li ";
+			if(focusIndex==index){
+				html +="class='trem_focus' "
+			}
+			html += "onclick=\"term_insert('"+it.word+"')\" ";
+			
+			html +=">";
+			html +=index+ ". ";
+			if(it.exist>0){
+				html += "<b>"+it.word+"</b>";
+			}else{
+				html +=it.word;
+			}
+			html +="<li>";
+			term_filterd_data.push(it.word);
+			if(index>_term_max_menu){
+				break;
+			}
+		}
+
+	}
+	return html;
+}
+
+//添加自动格位数据到内存字典
+function term_parent(paliword) {
+	let output=[];
+	for (const it of gCaseTable) {
+		if (it.type != ".v.") {
+			let sEnd2 = paliword.slice(0 - it.end2.length);
+			if (sEnd2 == it.end2) {
+				let wordParent = paliword.slice(0, 0 - it.end2.length) + it.end1;
+				output[wordParent]=1;
+			}
+		}		
+	}
+	return output;
+}

+ 76 - 0
app/term/term.css

@@ -707,6 +707,7 @@ pw {
 	display: none;
 }
 .body > .edit textarea {
+	/*
 	color: var(--main-color);
 	width: 100%;
 	background-color: var(--drop-bg-color);
@@ -716,6 +717,7 @@ pw {
 	line-height: 1.5em;
 	height: 90px;
 	font-size: 120%;
+	*/
 }
 .foot_bar {
 	font-size: 90%;
@@ -994,4 +996,78 @@ pali>p {
     text-align: center;
     display: inline-block;
     margin-left: 5px;
+}
+
+/*术语输入AT弹出菜单*/
+.text_input>.textarea{
+	padding: 5px;
+	font-family: inherit;
+	width: 100%;
+	height: 100px;
+	resize: vertical;
+	font-size: 14px;
+	line-height: 1;
+	border: 1px solid #ddd;
+	white-space: pre-wrap;
+	word-break: break-all;
+	z-index: 1;
+	resize: vertical;
+	color: var(--main-color);
+	width: 100%;
+	background-color: var(--drop-bg-color);
+	border: unset;
+	border-radius: 8px;
+	padding: 5px;
+	line-height: 1.5em;
+}
+.text_input>.text_shadow{
+	position: absolute;
+	width: 100%;
+	visibility: hidden;
+}
+.text_input .cursor{
+	position: absolute;
+	border-left: 1px solid #000;
+}
+.text_input>.menu{
+	width: 200px;
+	height:300px;
+	background-color: var(--tool-bg-color);
+    color: var(--btn-color);
+	box-shadow: #000;
+	position:absolute;
+	display: none;
+	z-index: 100;
+	box-shadow: 0 5px 7px rgb(0 0 0 / 15%);
+}
+.text_input>.menu ul{
+	list-style-type: none;
+	margin: 0;
+	padding: 0;
+}
+.text_input>.menu ul li{
+	cursor: pointer;
+}
+.text_input>.menu ul li:hover{
+	background-color: var(--btn-border-color);
+}
+
+.term_at_menu_input{
+	padding: 5px;
+    border-bottom: 1px solid gray;
+}
+.text_input{
+	width:100%;
+	position: relative;
+}
+
+.term_mean {
+    text-transform: capitalize;
+}
+.term_at_menu_ul>.trem_focus{
+	border-radius:unset;
+	box-shadow:unset;
+	margin:unset;
+	padding:unset;
+	background-color: var(--btn-border-color);
 }

+ 0 - 276
app/term/text_compare.html

@@ -1,276 +0,0 @@
-<!DOCTYPE html>
-<html>
-	<head>
-		<title>文本比较工具</title>
-		<style type="text/css">
-			* {
-				padding: 0px;
-				margin: 0px;
-			}
-			html,
-			body {
-				overflow-y: hidden;
-			}
-			.edit_div {
-				border: 1px solid #cccccc;
-				overflow: auto;
-				position: relative;
-			}
-			.edit_div textarea {
-				resize: none;
-				background: none repeat scroll 0 0 transparent;
-				border: 0 none;
-				width: 100%;
-				height: 200px;
-				overflow-y: scroll;
-				position: absolute;
-				left: 0px;
-				top: 0px;
-				z-index: 2;
-				font-size: 18px;
-				white-space: pre-wrap;
-				word-wrap: break-word;
-				word-break: break-all;
-			}
-			.edit_div pre {
-				overflow-y: scroll;
-				white-space: pre-wrap;
-				word-wrap: break-word;
-				word-break: break-all;
-				width: 100%;
-				height: 200px;
-				text-align: left;
-				color: #ffffff;
-				z-index: 1;
-				font-size: 18px;
-			}
-		</style>
-	</head>
-	<body>
-		<table style="width: 100%">
-			<tr>
-				<td style="width: 50%">
-					<div class="edit_div">
-						<pre id="edit_pre_1"></pre>
-						<textarea
-							id="edit_textarea_1"
-							onscroll="test1_scroll()"
-							oninput="textchange()"
-							onpropertychange="textchange()"
-						></textarea>
-					</div>
-				</td>
-				<td style="width: 50%">
-					<div class="edit_div">
-						<pre id="edit_pre_2"></pre>
-						<textarea
-							id="edit_textarea_2"
-							onscroll="test2_scroll()"
-							oninput="textchange()"
-							onpropertychange="textchange()"
-						></textarea>
-					</div>
-				</td>
-			</tr>
-		</table>
-		<script type="text/javascript">
-			function test1_scroll() {
-				document.getElementById("edit_pre_1").scrollTop = document.getElementById("edit_textarea_1").scrollTop;
-				document.getElementById("edit_pre_2").scrollTop = document.getElementById("edit_pre_1").scrollTop;
-				document.getElementById("edit_textarea_2").scrollTop = document.getElementById(
-					"edit_textarea_1"
-				).scrollTop;
-			}
-			function test2_scroll() {
-				document.getElementById("edit_pre_2").scrollTop = document.getElementById("edit_textarea_2").scrollTop;
-				document.getElementById("edit_pre_1").scrollTop = document.getElementById("edit_pre_2").scrollTop;
-				document.getElementById("edit_textarea_1").scrollTop = document.getElementById(
-					"edit_textarea_2"
-				).scrollTop;
-			}
-			function textchange() {
-				var op = eq({
-					value1: document.getElementById("edit_textarea_1").value,
-					value2: document.getElementById("edit_textarea_2").value,
-				});
-				document.getElementById("edit_pre_1").innerHTML = op.value1 + "\r\n";
-				document.getElementById("edit_pre_2").innerHTML = op.value2 + "\r\n";
-			}
-			function eq(op) {
-				if (!op) {
-					return op;
-				}
-				if (!op.value1_style) {
-					op.value1_style = "background-color:#FEC8C8;";
-				}
-				if (!op.value2_style) {
-					op.value2_style = "background-color:#FEC8C8;";
-				}
-				if (!op.eq_min) {
-					op.eq_min = 3;
-				}
-				if (!op.eq_index) {
-					op.eq_index = 5;
-				}
-				if (!op.value1 || !op.value2) {
-					return op;
-				}
-				var ps = {
-					v1_i: 0,
-					v1_new_value: "",
-					v2_i: 0,
-					v2_new_value: "",
-				};
-				while (ps.v1_i < op.value1.length && ps.v2_i < op.value2.length) {
-					if (op.value1[ps.v1_i] == op.value2[ps.v2_i]) {
-						ps.v1_new_value += op.value1[ps.v1_i].replace(/</g, "<").replace(">", ">");
-						ps.v2_new_value += op.value2[ps.v2_i].replace(/</g, "<").replace(">", ">");
-						ps.v1_i += 1;
-						ps.v2_i += 1;
-						if (ps.v1_i >= op.value1.length) {
-							ps.v2_new_value +=
-								"<span style='" +
-								op.value2_style +
-								"'>" +
-								op.value2.substr(ps.v2_i).replace(/</g, "<").replace(">", ">") +
-								"</span>";
-							break;
-						}
-						if (ps.v2_i >= op.value2.length) {
-							ps.v1_new_value +=
-								"<span style='" +
-								op.value1_style +
-								"'>" +
-								op.value1.substr(ps.v1_i).replace(/</g, "<").replace(">", ">") +
-								"</span>";
-							break;
-						}
-					} else {
-						ps.v1_index = ps.v1_i + 1;
-						ps.v1_eq_length = 0;
-						ps.v1_eq_max = 0;
-						ps.v1_start = ps.v1_i + 1;
-						while (ps.v1_index < op.value1.length) {
-							if (op.value1[ps.v1_index] == op.value2[ps.v2_i + ps.v1_eq_length]) {
-								ps.v1_eq_length += 1;
-							} else if (ps.v1_eq_length > 0) {
-								if (ps.v1_eq_max < ps.v1_eq_length) {
-									ps.v1_eq_max = ps.v1_eq_length;
-									ps.v1_start = ps.v1_index - ps.v1_eq_length;
-								}
-								ps.v1_eq_length = 0;
-								break; //只寻找最近的
-							}
-							ps.v1_index += 1;
-						}
-						if (ps.v1_eq_max < ps.v1_eq_length) {
-							ps.v1_eq_max = ps.v1_eq_length;
-							ps.v1_start = ps.v1_index - ps.v1_eq_length;
-						}
-
-						ps.v2_index = ps.v2_i + 1;
-						ps.v2_eq_length = 0;
-						ps.v2_eq_max = 0;
-						ps.v2_start = ps.v2_i + 1;
-						while (ps.v2_index < op.value2.length) {
-							if (op.value2[ps.v2_index] == op.value1[ps.v1_i + ps.v2_eq_length]) {
-								ps.v2_eq_length += 1;
-							} else if (ps.v2_eq_length > 0) {
-								if (ps.v2_eq_max < ps.v2_eq_length) {
-									ps.v2_eq_max = ps.v2_eq_length;
-									ps.v2_start = ps.v2_index - ps.v2_eq_length;
-								}
-								ps.v1_eq_length = 0;
-								break; //只寻找最近的
-							}
-							ps.v2_index += 1;
-						}
-						if (ps.v2_eq_max < ps.v2_eq_length) {
-							ps.v2_eq_max = ps.v2_eq_length;
-							ps.v2_start = ps.v2_index - ps.v2_eq_length;
-						}
-						if (ps.v1_eq_max < op.eq_min && ps.v1_start - ps.v1_i > op.eq_index) {
-							ps.v1_eq_max = 0;
-						}
-						if (ps.v2_eq_max < op.eq_min && ps.v2_start - ps.v2_i > op.eq_index) {
-							ps.v2_eq_max = 0;
-						}
-						if (ps.v1_eq_max == 0 && ps.v2_eq_max == 0) {
-							ps.v1_new_value +=
-								"<span style='" +
-								op.value1_style +
-								"'>" +
-								op.value1[ps.v1_i].replace(/</g, "<").replace(">", ">") +
-								"</span>";
-							ps.v2_new_value +=
-								"<span style='" +
-								op.value2_style +
-								"'>" +
-								op.value2[ps.v2_i].replace(/</g, "<").replace(">", ">") +
-								"</span>";
-							ps.v1_i += 1;
-							ps.v2_i += 1;
-
-							if (ps.v1_i >= op.value1.length) {
-								ps.v2_new_value +=
-									"<span style='" +
-									op.value2_style +
-									"'>" +
-									op.value2.substr(ps.v2_i).replace(/</g, "<").replace(">", ">") +
-									"</span>";
-								break;
-							}
-							if (ps.v2_i >= op.value2.length) {
-								ps.v1_new_value +=
-									"<span style='" +
-									op.value1_style +
-									"'>" +
-									op.value1.substr(ps.v1_i).replace(/</g, "<").replace(">", ">") +
-									"</span>";
-								break;
-							}
-						} else if (ps.v1_eq_max > ps.v2_eq_max) {
-							ps.v1_new_value +=
-								"<span style='" +
-								op.value1_style +
-								"'>" +
-								op.value1
-									.substr(ps.v1_i, ps.v1_start - ps.v1_i)
-									.replace(/</g, "<")
-									.replace(">", ">") +
-								"</span>";
-							ps.v1_i = ps.v1_start;
-						} else {
-							ps.v2_new_value +=
-								"<span style='" +
-								op.value2_style +
-								"'>" +
-								op.value2
-									.substr(ps.v2_i, ps.v2_start - ps.v2_i)
-									.replace(/</g, "<")
-									.replace(">", ">") +
-								"</span>";
-							ps.v2_i = ps.v2_start;
-						}
-					}
-				}
-				op.value1 = ps.v1_new_value;
-				op.value2 = ps.v2_new_value;
-				return op;
-			}
-			function settextheight() {
-				var heigth = document.documentElement.clientHeight - 6 + "px";
-				document.getElementById("edit_pre_1").style.height = heigth;
-				document.getElementById("edit_textarea_1").style.height = heigth;
-				document.getElementById("edit_pre_2").style.height = heigth;
-				document.getElementById("edit_textarea_2").style.height = heigth;
-			}
-			window.onload = function () {
-				settextheight();
-				window.onresize = function () {
-					settextheight();
-				};
-			};
-		</script>
-	</body>
-</html>

+ 151 - 75
app/widget/term_input.html

@@ -2,9 +2,8 @@
 <html>
 	<body>
 		<style>
-			.textarea,
-			textarea {
-				padding: 0;
+			.text_input>.textarea{
+				padding: 5px;
 				font-family: inherit;
 				width: 100%;
 				height: 100px;
@@ -15,54 +14,87 @@
 				white-space: pre-wrap;
 				word-break: break-all;
 				z-index: 1;
+				resize: vertical;
 			}
-			#text_shadow{
+			.text_input>.text_shadow{
 				position: absolute;
-				width: 300px;
+				width: 100%;
 				visibility: hidden;
 			}
-			.cursor{
+			.text_input .cursor{
 				position: absolute;
 				border-left: 1px solid #000;
 			}
-			#menu{
+			.text_input>.menu{
 				width: 200px;
 				height:300px;
 				background-color: aqua;
 				box-shadow: #000;
 				position:absolute;
 				display: none;
+				z-index: 100;
 			}
-			#menu ul{
+			.text_input>.menu ul{
 				list-style-type: none;
-    margin: 0;
-    padding: 0;
+				margin: 0;
+				padding: 0;
+			}
+			.text_input>.menu ul li{
+				cursor: pointer;
+			}
+			.text_input>.menu ul li:hover{
+				background-color: wheat;
 			}
-			#menu .focus{
+			.text_input>.menu .focus{
 				color:red;
 			}
+			.term_at_menu_input{
+				height:1em;
+				border: 1px solid gray;
+			}
+			.text_input{
+				width:100%;
+				position: relative;
+			}
 		</style>
 
 <h2>术语输入测试</h2>
-<div style='width:300px;position: relative;'>
-<div id="menu"></div>
-<div class="textarea" id="text_shadow" >
-前端路迹<span class="cursor">&nbsp;</span>
-qinshenxue.com
-</div>
-<textarea>
-前端路迹
-qinshenxue.com
-</textarea>
-</div>
+<div id="kk" style="width:50%;"></div>
+
+<h2>术语输入测试</h2>
+<div id="mm" style="width:60%;"></div>
+
 
 <script>
 	var menuFocusIndex=0;
-	var data=["amanussa","anadhiṭṭhita","anantarāya","anissaṭṭha","aniyata","antaravāsaka"];
-	var textarea = document.querySelector('textarea');
-	textarea.onkeydown = function (e) {
-		textarea.clientHeight
-		let menu = document.querySelector('#menu');
+	var term_data=["amanussa","anadhiṭṭhita","anantarāya","anissaṭṭha","aniyata","antaravāsaka"];
+	var term_input_text ;
+	var term_input="";
+	document.querySelector("#kk").innerHTML = term_render_text_input("test1 http://aa.org/?book=1&para=1");
+	document.querySelector("#mm").innerHTML =  term_render_text_input("test1 http://aa.org/?book=1&para=1");
+	function term_render_text_input(text){
+		let html ="";
+		html += '<div class="text_input" >';
+		html += '<div class="menu"></div>';
+		html += '<div class="textarea text_shadow"></div>';
+		html += '<textarea class="textarea tran_sent_textarea" onfocus="text_input_textarea_focuse(this)">';
+		html += text;
+		html += '</textarea> ';
+		html += '</div>';
+		return html;
+	}
+	function term_set_word_list_data(el){
+		term_data=["amanussa","anadhiṭṭhita","anantarāya","anissaṭṭha","aniyata","antaravāsaka"];
+	}
+	function text_input_textarea_focuse(el){
+		term_set_word_list_data(el);
+		term_input_text = el;
+		term_input_text.onresize = function(){
+			term_input_text.parentElement.querySelector(".text_shadow").style.height=term_input_text.style.height;
+		}
+		term_input_text.onkeydown = function (e) {
+		term_input_text.style.height = term_input_text.parentElement.querySelector(".text_shadow").scrollHeight
+		let menu = term_input_text.parentElement.querySelector('.menu');
 		switch (e.key) {
 			case "ArrowDown"://down arrow
 				if(menu.style.display=="block"){
@@ -70,7 +102,7 @@ qinshenxue.com
 					if(menuFocusIndex>5){
 						menuFocusIndex=5;
 					}
-					menu.innerHTML=renderMenu({focus:menuFocusIndex});
+					menu.innerHTML=TermAtRenderMenu({focus:menuFocusIndex});
 					return false;					
 				}
 				break;
@@ -80,80 +112,124 @@ qinshenxue.com
 					if(menuFocusIndex<0){
 						menuFocusIndex=0;
 					}
-					menu.innerHTML=renderMenu({focus:menuFocusIndex});
+					menu.innerHTML=TermAtRenderMenu({focus:menuFocusIndex});
 					return false;					
 				}
 			break;
 			case "Enter":
 				if(menu.style.display=="block"){
-					let value = textarea.value;
-					let selectionStart = textarea.selectionStart;
-					let str1 = value.slice(0, selectionStart)
-					let str2 = value.slice(selectionStart);
-					textarea.value = str1+data[menuFocusIndex]+"]]"+str2;
-					menu.style.display="none";
+					term_insert(term_data[menuFocusIndex]);
 					return false;
 				}
+				/*
 				else{
 					if(!e.shiftKey){
 						return false;
 					}
-				}
+				}*/
 				
 				break;
 			case "Escape":
-				e.currentTarget.value="";
+				break;
+			case "ArrowLeft":
+				if(menu.style.display=="block"){
+					return false;
+				}
+				break;
+			case "ArrowRight":
+				if(menu.style.display=="block"){
+					return false;
+				}
+				break;
+			case "Backspace":
+				if(menu.style.display=="block"){
+					if(term_input.length>0){
+						term_input = term_input.slice(0,-1);
+						menu.innerHTML=TermAtRenderMenu({focus:menuFocusIndex});						
+					}
+					return false;
+				}
 				break;
 			default:
+				if(menu.style.display=="block"){
+					term_input += e.key;
+					menu.innerHTML=TermAtRenderMenu({focus:menuFocusIndex});
+					return false;
+
+				}
 				break;
 		}
 	}
-	textarea.onkeyup = function (e) {
-		let value = textarea.value
-		let selectionStart = textarea.selectionStart
-		let str1 = value.slice(0, selectionStart)
-		let str2 = value.slice(selectionStart)
-		let textNode1 = document.createTextNode(str1)
-		let textNode2 = document.createTextNode(str2)
-		let cursor = document.createElement('span')
-		cursor.innerHTML = '&nbsp;'
-		cursor.setAttribute('class','cursor')
-		let mirror = document.querySelector('.textarea')
-		mirror.innerHTML = ''
-		mirror.appendChild(textNode1)
-		mirror.appendChild(cursor)
-		mirror.appendChild(textNode2)
-		let menu = document.querySelector('#menu');		
-		if(str1.slice(-2)=="[[" && menu.style.display!="block"){
-			menuFocusIndex=0;
-			menu.innerHTML=renderMenu({focus:0});
-			menu.style.display="block";
-			menu.style.top=cursor.offsetTop+14;
-			menu.style.left=cursor.offsetLeft;
-		}
+		term_input_text.onkeyup = function (e) {
+			let value = term_input_text.value
+			let selectionStart = term_input_text.selectionStart
+			let str1 = value.slice(0, selectionStart)
+			let str2 = value.slice(selectionStart)
+			let textNode1 = document.createTextNode(str1)
+			let textNode2 = document.createTextNode(str2)
+			let cursor = document.createElement('span')
+			cursor.innerHTML = '&nbsp;'
+			cursor.setAttribute('class','cursor')
+			let mirror = term_input_text.parentElement.querySelector('.text_shadow')
+			mirror.innerHTML = ''
+			mirror.appendChild(textNode1)
+			mirror.appendChild(cursor)
+			mirror.appendChild(textNode2)
+			let menu = term_input_text.parentElement.querySelector('.menu');	
+			if(str1.slice(-2)=="[[" && menu.style.display!="block"){
+				menuFocusIndex=0;
+				menu.innerHTML=TermAtRenderMenu({focus:0});
+				menu.style.display="block";
+				menu.style.top=cursor.offsetTop+14;
+				menu.style.left=cursor.offsetLeft;
+			}
 
-		if(e.key=="Escape"){
-			menu.style.display="none";
-		}
-		
-		console.log(keynum);
-		console.log(cursor.offsetLeft,cursor.offsetTop)
+			if(e.key=="Escape"){
+				term_at_menu_hide();
+			}
+			
+			console.log(e);
+			console.log(cursor.offsetLeft,cursor.offsetTop)
+	}
+	
 	}
-	function renderMenu(params) {
+
+	function term_at_menu_hide(){
+		let menu = term_input_text.parentElement.querySelector('.menu');
+		menu.style.display="none";
+		term_input="";
+	}
+	function term_insert(strTerm){
+		let value = term_input_text.value;
+		let selectionStart = term_input_text.selectionStart;
+		let str1 = value.slice(0, selectionStart)
+		let str2 = value.slice(selectionStart);
+		//TODO 光标会跑到最下面
+		term_input_text.value = str1+strTerm+"]]"+str2;
+		term_at_menu_hide();
+	}
+	function TermAtRenderMenu(params) {
 		
-		let html="<ul>";
+		let html="";
+		html +="<div class='term_at_menu_input'>"+term_input+"|</div>";
+		html +="<ul class='term_at_menu_ul'>";
 		let index=0;
-		let focusIndex = params.focus%data.length;
-		for (const it of data) {
-			html +="<li ";
-			if(focusIndex==index){
-				html +="class='focus' "
+		let focusIndex = params.focus%term_data.length;
+		for (const it of term_data) {
+			if(term_input=="" || it.indexOf(term_input)!=-1){
+				html +="<li ";
+				if(focusIndex==index){
+					html +="class='focus' "
+				}
+				html += "onclick=\"term_insert('"+it+"')\" ";
+				index++;
+				html +=">"+index+ ". "+it+"<li>";
 			}
-			index++;
-			html +=">"+index+ ". "+it+"<li>";
+
 		}
 		return html;
 	}
+	
 	/*
 	// element:  t.refs.textarea
 function getCaretPosition(element) {