failed-type-setting-project/script.ts
2021-05-25 20:30:40 +08:00

318 lines
No EOL
9.1 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

document.getElementById("info").innerHTML += "paper width (px)" + document.getElementById("paper").offsetWidth + "<br/>";
function css( element : HTMLElement, property : string ) {
return window.getComputedStyle( element, null ).getPropertyValue( property );
}
let paper = document.getElementById('paper');
let paperPage1 = document.getElementById('paper-page1');
var font_family = css( paper, 'font-family')
var font_size = css(paper, 'font-size')
paper.addEventListener('input', getWordsWidth);
paper.addEventListener('keydown', (e)=>{
if(e.key==" "){ //enter
e.preventDefault(); //Prevent default browser behavior
var sel : Selection;
var range : Range;
sel = window.getSelection();
range = sel.getRangeAt(0);
range.deleteContents();
var textNode = document.createTextNode('\u00A0'); // no linebreaking-space
range.insertNode(textNode);
range.setStartAfter(textNode);
sel.addRange(range);
getWordsWidth();
// paper.innerHTML+= paper.innerHTML;
//var currentPage = document.getElementById(getCaretCurrentPageId());
//var currentRange = getCursorLengthRange(currentPage);
//var HTMLBeforeCaret = rangeToHTMLFragement(currentRange);
}
});
// 如果游標在 contentdiveditable id "paper-page1" 裡面,
// 該函數返回 "paper-page1"
function getCaretCurrentPageId(){
var anchorNode = window.getSelection().anchorNode;
var currentNode = anchorNode;
while((currentNode as Element).id === undefined || !((currentNode as Element).id.match(/^paper-page\d+/))){
currentNode = currentNode.parentNode;
}
return (currentNode as Element).id;
}
// 得到子節點(文字物件)
// ["dolore", [ "m ips", ["um si"], "t am"], "et"]
function getChildNodes(ele : HTMLElement){
var res_array
res_array = [];
if (ele.nodeType == Node.TEXT_NODE){
return ele;
}else{
for (var i =0; i <ele.childNodes.length;i++){
res_array.push(getChildNodes(<HTMLElement>(ele.childNodes[i])))
}
return res_array
}
}
// 平坦化陣列
// [a, [b, c, d], [[e]]] => [a, b, c, d, e]
function flatten(arr){
if (!Array.isArray(arr)){
return arr;
}
else{
var result = [];
for (var i=0;i<arr.length;i++){
if (Array.isArray(arr[i])){
result = result.concat(flatten(arr[i]))
}
else{
result.push(arr[i])
}
}
return result;
}
}
/* 從第幾個字到第幾個字選 range. */
function selecRengeFromCharToChar(i : number, j : number, ele: ElementContentEditable){
var range = document.createRange();
var sel = document.getSelection();
var flattened_ar = flatten(getChildNodes(<HTMLElement>ele));
range.selectNodeContents((<Node><unknown>ele));
var ran_start = i
var ran_end = j
var ran_start_is_set = false
for (var i=0; i< flattened_ar.length;i++){
var fragement_text_length = flattened_ar[i].textContent.length;
// 如果 ran_start > 碎片長度
if(ran_start > fragement_text_length){
ran_start -= fragement_text_length;
ran_end -= fragement_text_length;
// 如果 ran_start <= 碎片長度
}else if(ran_start <= fragement_text_length && ran_start_is_set == false){
range.setStart(flattened_ar[i], ran_start);
ran_start_is_set = true
// 如果 ran_end > 碎片長度
if (ran_end > fragement_text_length){
ran_end -= fragement_text_length;
// 如果 ran_end <= 碎片長度setEnd 中止迴圈
}else{
range.setEnd(flattened_ar[i], ran_end);
break;
}
// 如果 ran_end > 碎片長度
}else if (ran_end > fragement_text_length && ran_start_is_set == true){
ran_end -= fragement_text_length;
}
// 如果 ran_end <= 碎片長度setEnd 中止迴圈
else{
range.setEnd(flattened_ar[i], ran_end);
break;
}
}
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
return range
}
/*
設置游標位置於 ele 要素的第 col 個字(不含標籤),例子:
HTML <div>dolore<i>m ips<b>um si</b>t am</i>et&nbsp;1234<div>
setCaret(document.getElementById('paper-page1'),10)
V CARET
<div>dolore<i>m ip|s<b>um si</b>t am</i>et&nbsp;1234<div>
*/
function setCaret(ele: ElementContentEditable, col : number){
var range = document.createRange();
var sel = document.getSelection();
var flattened_ar = flatten(getChildNodes(<HTMLElement>ele)); // flattened array
range.selectNodeContents((<Node><unknown>ele));
var ran_start = col
for (var i=0; i< flattened_ar.length;i++){
var fragement_text_length = flattened_ar[i].textContent.length;
if(ran_start > fragement_text_length){
ran_start -= fragement_text_length;
}else{
range.setEnd(flattened_ar[i], ran_start);
range.collapse();
break;
}
}
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
}
// 將座標轉成座標所在位置的 range
function getCursorLengthRange(ele: HTMLElement){
let win = ele.ownerDocument.defaultView;
let range = win.getSelection().getRangeAt(0);
let cloneRange = range.cloneRange();
cloneRange.selectNodeContents(ele);
cloneRange.setEnd(range.endContainer, range.endOffset);
return cloneRange;
}
// 將座標 range 轉成字串的長度
function rangeToStringLen(range : Range){
return range.toString().length;
}
// 將座標位置 range 轉成 html 斷片
function rangeToHTMLFragement(range : Range){
var nodes =range.cloneContents().childNodes;
var result = ""
for(var i=0;i<nodes.length;i++){
let parentNode = (<DocumentFragment> nodes[i].parentNode);
let div=document.createElement("div");
div.appendChild(parentNode);
if (typeof ((<HTMLElement> nodes[i]).outerHTML) === "undefined"){
result += nodes[i].textContent;}
else{
result += (<HTMLElement> nodes[i]).outerHTML;}
console.log("Parent Node"+div.outerHTML);
}
return result;
}
// 得到一個 word 或是 character 的寬度
function getTextWidth(text, fontfamily, fontsize) {
console.log(text)
var decodedText = decodeEntities(text)
let canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
context.font = fontsize + " " + fontfamily;
let width = context.measureText(decodedText).width;
return width;
}
// 得到字寬
function getWordsWidth(){
document.getElementById('line-info').innerHTML = "";
var array = paper.childNodes;
var res = [];
for (var i=0;i<array.length;i++){
if( array[i].nodeType != Node.TEXT_NODE){
res.push(array[i]);
}
}
var innerArray = res.map((x)=>x.innerHTML);
var innerHTMLTotal = innerArray.reduce((x,y)=>(x+y));
var innerHTMLRemoveTags = innerHTMLTotal.replace(/[<][\/]?[^<]+[\/]?[>]/gi,"") // 移除標籤
var innerHTMLSplitted = innerHTMLRemoveTags.split(/( |\s|&nbsp;|[⺀-\u2efe\u3000-〾㇀-\u31ee㌀-㏾㐀-\u4dbe一-\u9ffe豈-\ufafe-]|[\ud840-\ud868\ud86a-\ud86c][\udc00-\udfff]|\ud869[\udc00-\udede\udf00-\udfff]|\ud86d[\udc00-\udf3e\udf40-\udfff]|\ud86e[\udc00-\udc1e]|\ud87e[\udc00-\ude1e])/).filter(item => item != "")
console.log(innerHTMLSplitted);
//var innerHTMLSplittedLength = innerHTMLSplitted.map((x)=>x.length)
//var innerHTMLSelectedRange = [];
/*var sum = 0
for (var i=0; i<innerHTMLSplittedLength.length;i++){
var head = sum;
var tail = sum + innerHTMLSplittedLength[i];
innerHTMLSelectedRange.push([head, tail]);
sum+= innerHTMLSplittedLength[i];
}*/
/*var innerHTMLSplittedRange = innerHTMLSelectedRange.map((x) => rangeToHTMLFragement(selecRengeFromCharToChar(x[0],x[1],paper)))
console.log("Range 結果"+innerHTMLSplittedRange);*/
let textWidthList = innerHTMLSplitted.map(x => getTextWidth(x,font_family, font_size));
var lineInfoLength = [];
for (var i=0; i<innerHTMLSplitted.length;i++){
var object = {"content":innerHTMLSplitted[i],
"length":textWidthList[i]}
document.getElementById("line-info").innerHTML += "(" + innerHTMLSplitted[i] + ",";
document.getElementById("line-info").innerHTML += textWidthList[i] + ")";
lineInfoLength.push(object);
}
// document.getElementById("info").innerHTML += lineInfoLength;
}
// 將要在地幾個字插入符號,改為修正為在有標籤的 HTML 的片段中,第幾個不算標籤的字插入符號
/*
> getrealcol(5, "example")
> 5
> getrealcol(5, "e<em>xam</em>ple")
> 14
*/
function getrealcol(n, str) {
var arr = str.split(RegExp("(<[^<>]+>)")).map((x) => ({ cont: x, len: x.length }));
var j = 0;
var k = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i].cont.match(/^[<]/)) { continue; }
else {
if (n > arr[i].len) { n = n - arr[i].len; }
else { j = i; k = n; break; }
};
}
var res_col = 0;
for (var i = 0; i < j; i++) {
res_col += arr[i].len;
}
res_col += k;
return res_col;
}
// 解碼 &1234; 這種東西用
function decodeEntities(encodedString) {
var textArea = document.createElement('textarea');
textArea.innerHTML = encodedString;
return textArea.value;
}