3723 lines
136 KiB
JavaScript
3723 lines
136 KiB
JavaScript
/*if (typeof console == "undefined") {
|
|
this.console = { log: function (msg) { alert(msg); } };
|
|
}*/
|
|
|
|
/*
|
|
text selection - double click should select word
|
|
cursor up/down - remember horizPos of original line and find closest in other lines
|
|
|
|
*/
|
|
|
|
/* example of basic use:
|
|
var j000inputs = inputs({
|
|
inputs:[
|
|
{left:900,top:300,width:100,height:50,algText:true},
|
|
{left:900,top:500,width:100,height:50,algText:true}
|
|
],
|
|
leftText:[
|
|
['Perimeter = '],
|
|
['Area = ']
|
|
],
|
|
rightText:[
|
|
['cm'],
|
|
['cm',['pow',false,['2']]]
|
|
],
|
|
checkFuncs:[
|
|
function(mathsInput) {
|
|
if (mathsInput.stringJS == 'correctAns') {
|
|
return true;
|
|
} else {
|
|
return false
|
|
}
|
|
},
|
|
function(mathsInput) {
|
|
if (mathsInput.stringJS == 'correctAns') {
|
|
return true;
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
],
|
|
});
|
|
*/
|
|
function inputs(object) {
|
|
var inputs = object.inputs;
|
|
var checkFuncs = object.checkFuncs;
|
|
var buttonPos = object.buttonPos || [990,620];
|
|
var taskComplete = boolean(object.taskCompleted,true);
|
|
var buttonVis = boolean(object.buttonVisible,true);
|
|
|
|
var inputArray = [];
|
|
|
|
for (var i = 0; i < inputs.length; i++) {
|
|
var zIndex = inputs[i].zIndex || 2;
|
|
// mathsInput
|
|
var input = createMathsInput2(inputs[i]);
|
|
var vis = boolean(inputs[i].visible,true);
|
|
|
|
// leftText && rightText
|
|
var button3 = document.createElement('canvas');
|
|
button3.width = 1200;
|
|
button3.height = 700;
|
|
button3.setAttribute('position', 'absolute');
|
|
button3.setAttribute('cursor', 'auto');
|
|
button3.setAttribute('draggable', 'false');
|
|
button3.setAttribute('class', 'buttonClass');
|
|
var data3 = [0,0,1200,700,vis,false,false,zIndex];
|
|
if (vis == true) container.appendChild(button3);
|
|
data3[130] = true;
|
|
for (var j = 0; j < 8; j++) {data3[100+j] = data3[j];}
|
|
button3.style.zIndex = zIndex;
|
|
button3.style.pointerEvents = 'none';
|
|
canvases[pageIndex].push(button3);
|
|
button3.data = data3;
|
|
button3.ctx = button3.getContext('2d');
|
|
|
|
if (typeof object.leftText == 'object') {
|
|
if (typeof object.leftText[i] == 'object') {
|
|
var maxLines = inputs[i].maxLines || 1;
|
|
var fontSize = inputs[i].fontSize || 0.5 * (inputs[i].height / maxLines);
|
|
var textColor = inputs[i].textColor || '#000';
|
|
drawMathsText(button3.ctx,object.leftText[i],fontSize,inputs[i].left-4,inputs[i].top+0.5*inputs[i].height,false,[],'right','middle',textColor);
|
|
input.leftText = object.leftText[i];
|
|
}
|
|
}
|
|
if (typeof object.rightText == 'object') {
|
|
if (typeof object.rightText[i] == 'object') {
|
|
var maxLines = inputs[i].maxLines || 1;
|
|
var fontSize = inputs[i].fontSize || 0.5 * (inputs[i].height / maxLines);
|
|
var textColor = inputs[i].textColor || '#000';
|
|
drawMathsText(button3.ctx,object.rightText[i],fontSize,inputs[i].left+inputs[i].width+15,inputs[i].top+0.5*inputs[i].height,false,[],'left','middle',textColor);
|
|
var textMeasure = drawMathsText(button3.ctx,object.rightText[i],fontSize,inputs[i].left+inputs[i].width+15,inputs[i].top+0.5*inputs[i].height,false,[],'left','middle',textColor,'measure');
|
|
if (typeof inputs[i].offset === 'undefined') inputs[i].offset = [textMeasure[0]+5,0];
|
|
input.rightText = object.rightText[i];
|
|
}
|
|
}
|
|
if (typeof inputs[i].offset === 'undefined') inputs[i].offset = [0,0];
|
|
|
|
input.leftRightTextCanvas = button3;
|
|
input.canvas.leftRightTextCanvas = button3;
|
|
|
|
// what if... maths input is entered through tab key, rather than clicking on??
|
|
addListener(input.canvas, function() {
|
|
hideObj(this.tick,this.tick.data);
|
|
hideObj(this.cross,this.cross.data);
|
|
});
|
|
|
|
// tick canvas
|
|
var button = document.createElement('canvas');
|
|
button.width = 40;
|
|
button.height = 50;
|
|
button.setAttribute('position', 'absolute');
|
|
button.setAttribute('cursor', 'auto');
|
|
button.setAttribute('draggable', 'false');
|
|
button.setAttribute('class', 'buttonClass');
|
|
var data = [inputs[i].left+inputs[i].width+13+inputs[i].offset[0],inputs[i].top+0.5*inputs[i].height-25+inputs[i].offset[1],40,50,false,false,false,zIndex];
|
|
data[130] = true;
|
|
for (var j = 0; j < 8; j++) {data[100+j] = data[j];}
|
|
button.style.zIndex = zIndex;
|
|
button.style.pointerEvents = 'none';
|
|
canvases[pageIndex].push(button3);
|
|
button.data = data;
|
|
button.ctx = button.getContext('2d');
|
|
drawTick(button.ctx,40,50);
|
|
|
|
// cross canvas
|
|
var button2 = document.createElement('canvas');
|
|
button2.width = 32;
|
|
button2.height = 40;
|
|
button2.setAttribute('position', 'absolute');
|
|
button2.setAttribute('cursor', 'auto');
|
|
button2.setAttribute('draggable', 'false');
|
|
button2.setAttribute('class', 'buttonClass');
|
|
var data2 = [inputs[i].left+inputs[i].width+20+inputs[i].offset[0],inputs[i].top+0.5*inputs[i].height-20+inputs[i].offset[1],32,40,false,false,false,zIndex];
|
|
data2[130] = true;
|
|
for (var j = 0; j < 8; j++) {data2[100+j] = data2[j];}
|
|
button2.style.zIndex = zIndex;
|
|
button.style.pointerEvents = 'none';
|
|
canvases[pageIndex].push(button3);
|
|
button2.data = data2;
|
|
button2.ctx = button2.getContext('2d');
|
|
drawCross(button2.ctx,32,40);
|
|
|
|
input.tick = button;
|
|
input.cross = button2;
|
|
input.canvas.tick = button;
|
|
input.canvas.cross = button2;
|
|
|
|
inputArray.push(input);
|
|
}
|
|
if (boolean(object.checkAnsButton,true)) {
|
|
// check answer button
|
|
var button = document.createElement('canvas');
|
|
button.width = 180;
|
|
button.height = 50;
|
|
button.setAttribute('position', 'absolute');
|
|
button.setAttribute('cursor', 'auto');
|
|
button.setAttribute('draggable', 'false');
|
|
button.setAttribute('class', 'buttonClass');
|
|
var data = [buttonPos[0],buttonPos[1],180,50,buttonVis,false,true,2];
|
|
if (buttonVis == true) container.appendChild(button);
|
|
data[130] = true;
|
|
for (var i = 0; i < 8; i++) {data[100+i] = data[i];}
|
|
button.style.zIndex = 2;
|
|
canvases[pageIndex].push(button3);
|
|
button.data = data;
|
|
button.ctx = button.getContext('2d');
|
|
if (inputs.length > 1) {
|
|
drawTextBox(button,button.ctx,button.data,'#6F9','#000',4,'28px Hobo','#000','center','Check Answers');
|
|
} else {
|
|
drawTextBox(button,button.ctx,button.data,'#6F9','#000',4,'28px Hobo','#000','center','Check Answer');
|
|
}
|
|
|
|
addListener(button,function() {
|
|
var inputs = this.inputs;
|
|
var checkFuncs = this.checkFuncs;
|
|
var complete = true;
|
|
for (var i = 0; i < inputs.length; i++) {
|
|
if (checkFuncs[i](inputs[i]) == true) {
|
|
hideObj(inputs[i].cross,inputs[i].cross.data);
|
|
showObj(inputs[i].tick,inputs[i].tick.data);
|
|
} else {
|
|
hideObj(inputs[i].tick,inputs[i].tick.data);
|
|
showObj(inputs[i].cross,inputs[i].cross.data,3000);
|
|
complete = false;
|
|
}
|
|
}
|
|
if (complete == true) {
|
|
taskCompleted();
|
|
}
|
|
});
|
|
|
|
button.inputs = inputArray;
|
|
button.checkFuncs = checkFuncs;
|
|
button.taskComplete = true;
|
|
button.textCanvas = button3;
|
|
return button;
|
|
}
|
|
}
|
|
|
|
function hideAllInputs() {
|
|
for (var i = 0; i < mathsInput[pageIndex].length; i++) {
|
|
hideMathsInput(mathsInput[pageIndex][i]);
|
|
}
|
|
}
|
|
function showAllInputs() {
|
|
for (var i = 0; i < mathsInput[pageIndex].length; i++) {
|
|
showMathsInput(mathsInput[pageIndex][i]);
|
|
}
|
|
}
|
|
function hideMathsInput(mathsInput) {
|
|
hideObj(mathsInput.canvas);
|
|
if (typeof mathsInput.cursorCanvas !== 'undefined') {
|
|
hideObj(mathsInput.cursorCanvas);
|
|
}
|
|
if (typeof mathsInput.tick !== 'undefined') {
|
|
hideObj(mathsInput.tick);
|
|
}
|
|
if (typeof mathsInput.cross !== 'undefined') {
|
|
hideObj(mathsInput.cross);
|
|
}
|
|
if (typeof mathsInput.leftRightTextCanvas !== 'undefined') {
|
|
hideObj(mathsInput.leftRightTextCanvas);
|
|
}
|
|
}
|
|
function showMathsInput(mathsInput) {
|
|
showObj(mathsInput.canvas);
|
|
if (typeof mathsInput.cursorCanvas !== 'undefined') {
|
|
showObj(mathsInput.cursorCanvas);
|
|
}
|
|
if (typeof mathsInput.leftRightTextCanvas !== 'undefined') {
|
|
showObj(mathsInput.leftRightTextCanvas);
|
|
}
|
|
}
|
|
function moveMathsInput(input,left,top) {
|
|
if (typeof input.data == 'undefined') return;
|
|
var dx = left - input.data[100];
|
|
var dy = top - input.data[101];
|
|
|
|
input.data[100] += dx;
|
|
input.data[101] += dy;
|
|
resizeCanvas2(input.canvas,input.data[100],input.data[101]);
|
|
|
|
if (typeof input.cross !== 'undefined') {
|
|
input.cross.data[100] += dx;
|
|
input.cross.data[101] += dy;
|
|
resizeCanvas2(input.cross,input.cross.data[100],input.cross.data[101]);
|
|
}
|
|
|
|
if (typeof input.tick !== 'undefined') {
|
|
input.tick.data[100] += dx;
|
|
input.tick.data[101] += dy;
|
|
resizeCanvas2(input.tick,input.tick.data[100],input.tick.data[101]);
|
|
}
|
|
|
|
input.cursorData[100] += dx;
|
|
input.cursorData[101] += dy;
|
|
resizeCanvas2(input.cursorCanvas,input.cursorData[100],input.cursorData[101]);
|
|
|
|
if (typeof input.leftRightTextCanvas !== 'undefined') {
|
|
input.leftRightTextCanvas.data[100] += dx;
|
|
input.leftRightTextCanvas.data[101] += dy;
|
|
resizeCanvas2(input.leftRightTextCanvas,input.leftRightTextCanvas.data[100],input.leftRightTextCanvas.data[101]);
|
|
}
|
|
}
|
|
function enlargeMathsInput(input,sf) { // be careful!
|
|
if (typeof sf !== 'number') return;
|
|
//var l = input.data[100];
|
|
//var t = input.data[101];
|
|
|
|
//input.data[102] = input.data[102] * sf;
|
|
//input.data[103] = input.data[103] * sf;
|
|
|
|
resizeCanvas(input.canvas,input.data[100],input.data[101],input.data[102]*sf,input.data[103]*sf);
|
|
|
|
/*input.cursorData[100] += (l -input.cursorData[100])*sf;
|
|
input.cursorData[101] += (t -input.cursorData[101])*sf;
|
|
input.cursorData[102] = input.cursorData[102] * sf;
|
|
input.cursorData[103] = input.cursorData[103] * sf;
|
|
resizeCanvas(input.cursorCanvas,input.cursorData[100],input.cursorData[101],input.cursorData[102],input.cursorData[103]);
|
|
|
|
if (typeof input.cross !== 'undefined') {
|
|
input.cross.data[100] += (l -input.cross.data[100])*sf;
|
|
input.cross.data[101] += (t -input.cross.data[101])*sf;
|
|
input.cross.data[102] = input.cross.data[102] * sf;
|
|
input.cross.data[103] = input.cross.data[103] * sf;
|
|
resizeCanvas(input.cross,input.cross.data[100],input.cross.data[101],input.cross.data[102],input.cross.data[103]);
|
|
}
|
|
|
|
if (typeof input.tick !== 'undefined') {
|
|
input.tick.data[100] += (l -input.tick.data[100])*sf;
|
|
input.tick.data[101] += (t -input.tick.data[101])*sf;
|
|
input.tick.data[102] = input.tick.data[102] * sf;
|
|
input.tick.data[103] = input.tick.data[103] * sf;
|
|
resizeCanvas(input.tick,input.tick.data[100],input.tick.data[101],input.tick.data[102],input.tick.data[103]);
|
|
}
|
|
|
|
if (typeof input.leftRightTextCanvas !== 'undefined') {
|
|
input.leftRightTextCanvas.data[100] += (l -input.leftRightTextCanvas.data[100])*sf;
|
|
input.leftRightTextCanvas.data[101] += (t -input.leftRightTextCanvas.data[101])*sf;
|
|
input.leftRightTextCanvas.data[102] = input.leftRightTextCanvas.data[102] * sf;
|
|
input.leftRightTextCanvas.data[103] = input.leftRightTextCanvas.data[103] * sf;
|
|
resizeCanvas(input.leftRightTextCanvas,input.leftRightTextCanvas.data[100],input.leftRightTextCanvas.data[101],input.leftRightTextCanvas.data[102],input.leftRightTextCanvas.data[103]);
|
|
}*/
|
|
}
|
|
function setMathsInputZIndex(input,zIndex) {
|
|
if (typeof input.leftRightTextCanvas == 'object') input.leftRightTextCanvas.style.zIndex = zIndex;
|
|
if (typeof input.tick == 'object') input.tick.style.zIndex = zIndex;
|
|
if (typeof input.cross == 'object') input.cross.style.zIndex = zIndex;
|
|
if (typeof input.canvas == 'object') input.canvas.style.zIndex = zIndex;
|
|
if (typeof input.cursorCanvas == 'object') input.cursorCanvas.style.zIndex = zIndex;
|
|
}
|
|
function setMathsInputFont(input,font) {
|
|
removeTagsOfType(input.richText,'font');
|
|
input.richText.unshift('<<font:'+font+'>>');
|
|
input.richText = combineSpacesTextArray(input.richText);
|
|
removeTagsOfType(input.startRichText,'font');
|
|
input.startRichText.unshift('<<font:'+font+'>>');
|
|
input.startRichText = combineSpacesTextArray(input.startRichText);
|
|
input.startTags = removeTagsOfType(input.startTags,'font');
|
|
input.startTags = '<<font:'+font+'>>'+input.startTags;
|
|
currMathsInput = input;
|
|
mathsInputMapCursorPos();
|
|
mathsInputCursorCoords();
|
|
deselectMathsInput();
|
|
}
|
|
function setMathsInputColor(input,color) {
|
|
removeTagsOfType(input.richText,'color');
|
|
input.richText.unshift('<<color:'+color+'>>');
|
|
input.richText = combineSpacesTextArray(input.richText);
|
|
removeTagsOfType(input.startRichText,'color');
|
|
input.startRichText.unshift('<<color:'+color+'>>');
|
|
input.startRichText = combineSpacesTextArray(input.startRichText);
|
|
input.startTags = removeTagsOfType(input.startTags,'color');
|
|
input.startTags = '<<color:'+color+'>>'+input.startTags;
|
|
var saveCurrMathsInput = currMathsInput;
|
|
currMathsInput = input;
|
|
drawMathsInputText(input);
|
|
deselectMathsInput();
|
|
}
|
|
function setMathsInputText(mathsInputObj, opt_newText, opt_newCursorPos) { // eg. setMathsInputText(j37mathsInput[3]);
|
|
var newText;
|
|
if (un(opt_newText)) {
|
|
newText = [""];
|
|
} else if (typeof opt_newText == 'string') {
|
|
newText = [opt_newText];
|
|
} else if (typeof opt_newText == 'number') {
|
|
newText = String(opt_newText);
|
|
newText = [newText];
|
|
} else {
|
|
newText = clone(opt_newText);
|
|
}
|
|
mathsInputObj.text = newText;
|
|
if (!un(mathsInputObj.startTags)) newText.unshift(mathsInputObj.startTags);
|
|
mathsInputObj.richText = newText;
|
|
currMathsInput = mathsInputObj;
|
|
mathsInputMapCursorPos();
|
|
if (typeof opt_newCursorPos !== 'undefined') {
|
|
mathsInputObj.cursorPos = opt_newCursorPos;
|
|
} else {
|
|
mathsInputObj.cursorPos = mathsInputObj.cursorMap.length - 1;
|
|
}
|
|
mathsInputCursorCoords();
|
|
deselectMathsInput();
|
|
}
|
|
function setMathsInputTextToInitialTags(m) {
|
|
var newText = "";
|
|
if (!un(m.richText) && typeof m.richText[0] == 'string' && m.richText[0].indexOf('<<') == 0) {
|
|
for (c = 2; c < m.richText[0].length; c++) {
|
|
if (m.richText[0].slice(c).indexOf('>>') == 0 && m.richText[0].slice(c).indexOf('>><<') !== 0) {
|
|
newText = m.richText[0].slice(0,c+2);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
setMathsInputText(m,[newText],0);
|
|
}
|
|
|
|
function drawTick(ctx,width,height,color,left,top,lineWidth) {
|
|
if (!left) left = 0;
|
|
if (!top) top = 0;
|
|
if (!width) width = 75;
|
|
if (!height) height = 75;
|
|
if (!color) color = '#F0F';
|
|
if(!lineWidth) lineWidth = 8;
|
|
ctx.save();
|
|
ctx.lineWidth = lineWidth;
|
|
ctx.strokeStyle = color;
|
|
ctx.lineJoin = 'round';
|
|
ctx.lineCap = 'round';
|
|
ctx.beginPath();
|
|
ctx.moveTo(left+4,top+0.5*height);
|
|
ctx.lineTo(left+width/3,top+height-4);
|
|
ctx.lineTo(left+width-4,top+4);
|
|
ctx.stroke();
|
|
ctx.restore();
|
|
}
|
|
function drawCross(ctx,width,height,color,left,top,lineWidth) {
|
|
if (!left) left = 0;
|
|
if (!top) top = 0;
|
|
if (!width) width = 75;
|
|
if (!height) height = 75;
|
|
if (!color) color = '#F00';
|
|
if(!lineWidth) lineWidth = 8;
|
|
ctx.save();
|
|
ctx.lineWidth = lineWidth;
|
|
ctx.strokeStyle = color;
|
|
ctx.lineJoin = 'round';
|
|
ctx.lineCap = 'round';
|
|
ctx.beginPath();
|
|
ctx.moveTo(left+4,top+4);
|
|
ctx.lineTo(left+width-4,top+height-4);
|
|
ctx.moveTo(left+width-4,top+4);
|
|
ctx.lineTo(left+4,top+height-4);
|
|
ctx.stroke();
|
|
ctx.restore();
|
|
}
|
|
|
|
function createMathsInput2(object) {
|
|
// non-optional:
|
|
var left = object.left;
|
|
var top = object.top;
|
|
var width = object.width;
|
|
var height = object.height;
|
|
|
|
// optional & defaults:
|
|
var varSize = object.varSize; // varSize:{minWidth:50,maxWidth:400,minHeight:50,maxHeight:300,padding:5}
|
|
var visible;
|
|
if (typeof object.visible == 'boolean') {visible = object.visible} else {visible = true};
|
|
var zIndex = object.zIndex || 2;
|
|
var algText;
|
|
if (typeof object.algText == 'boolean') {algText = object.algText} else {algText = false};
|
|
var textArray = object.textArray || [""];
|
|
var leftPoint = object.leftPoint || 10;
|
|
var textColor = object.textColor || '#000';
|
|
var textAlign = object.textAlign || 'center';
|
|
var vertAlign = object.vertAlign || 'middle';
|
|
var transparent;
|
|
if (typeof object.transparent == 'boolean') {transparent = object.transparent} else {transparent = false};
|
|
var maxChars = object.maxChars || 1000000000;
|
|
var backColor = object.backColor || '#FFF';
|
|
var selectColor = object.selectColor || '#FCF';
|
|
var border;
|
|
if (typeof object.border == 'boolean') {border = object.border} else {border = true};
|
|
var borderWidth = object.borderWidth || 3;
|
|
var borderDash = object.borderDash || [];
|
|
var borderColor = object.borderColor || '#000';
|
|
var maxLines = object.maxLines || 1;
|
|
var fontSize = object.fontSize || 0.5 * (height/maxLines);
|
|
var selectable = boolean(object.selectable,false);
|
|
var pointerCanvas = object.pointerCanvas || false;
|
|
|
|
var inputObject = createMathsInput(0, left, top, width, height, visible, zIndex, algText, textArray, leftPoint, fontSize, textColor, textAlign, transparent, maxChars, backColor, selectColor, border, borderColor, maxLines, vertAlign, varSize, borderWidth, borderDash, selectable, pointerCanvas);
|
|
return inputObject;
|
|
}
|
|
|
|
// creates mathsInput canvas
|
|
function createMathsInput(id, left, top, width, height, visible, zIndex, algText, textArray, leftPoint, fontSize, textColor, textAlign, transparent, maxChars, backColor, selectColor, border, borderColor, maxLines, vertAlign, varSize, borderWidth, borderDash,selectable, pointerCanvas) {
|
|
if (!maxLines) {maxLines = 1};
|
|
if (!zIndex) {zIndex = 2};
|
|
if (!algText) {algText = false};
|
|
if (!fontSize) (fontSize = (height/maxLines) * 0.75);
|
|
if (!textColor) (textColor = '#000');
|
|
if (!textAlign) {textAlign = 'center'};
|
|
if (textAlign == 'center') {leftPoint = 0.5 * width};
|
|
if (!vertAlign) {vertAlign = 'middle'};
|
|
if (!textArray) {textArray = [""]};
|
|
var font = 'Arial';
|
|
if (algText == true) font = 'algebra';
|
|
var startText = textArray.slice(0);
|
|
var startTags = "<<font:"+font+">><<fontSize:"+fontSize+">><<color:"+textColor+">><<backColor:none>><<bold:false>><<italic:false>><<align:"+textAlign+">>";
|
|
textArray.unshift(startTags);
|
|
var startRichText = textArray.slice(0);
|
|
if (!leftPoint) {leftPoint = 10};
|
|
if (typeof transparent !== 'boolean') {transparent = false};
|
|
if (!maxChars) {maxChars = 100000000}
|
|
if (!backColor) backColor = "#fff";
|
|
var currBackColor = backColor;
|
|
if (!selectColor) selectColor = '#FCF';
|
|
if (typeof border !== 'boolean') border = true;
|
|
if (!borderWidth) borderWidth = 5;
|
|
if (!borderDash) borderDash = [];
|
|
if (!borderColor) borderColor = '#000';
|
|
if (!startText) startText = [''];
|
|
if (typeof selectable !== 'boolean') selectable = false;
|
|
if (!pointerCanvas) pointerCanvas = false;
|
|
|
|
function makeInputCanvas(l,t,w,h,v,d,p,z) {
|
|
var canvas = document.createElement('canvas');
|
|
canvas.setAttribute('class', 'inputClass');
|
|
canvas.setAttribute('width', w);
|
|
canvas.setAttribute('height', h);
|
|
canvas.setAttribute('left', l);
|
|
canvas.setAttribute('top', t);
|
|
canvas.setAttribute('position', 'absolute');
|
|
canvas.style.border = 'none';
|
|
canvas.style.zIndex = z;
|
|
if (p == false) {
|
|
canvas.style.pointerEvents = 'none';
|
|
} else {
|
|
canvas.style.pointerEvents = 'auto';
|
|
}
|
|
canvas.data = [l,t,w,h,v,d,p,z];
|
|
canvas.ctx = canvas.getContext('2d');
|
|
for (var i = 0; i < 8; i++) {canvas.data[i+100] = canvas.data[i]};
|
|
resizeCanvas3(canvas);
|
|
return canvas;
|
|
}
|
|
|
|
var textCanvas = makeInputCanvas(left, top, width, height, visible, false, false, zIndex);
|
|
var cursorCanvas = makeInputCanvas(left, top, width, height, visible, false, true, zIndex);
|
|
cursorCanvas.addEventListener('mousedown', startMathsInput, false);
|
|
cursorCanvas.addEventListener('touchstart', startMathsInput, false);
|
|
|
|
var input = {
|
|
id:id,
|
|
canvas:textCanvas,
|
|
ctx:textCanvas.ctx,
|
|
data:textCanvas.data,
|
|
cursorCanvas:cursorCanvas,
|
|
cursorctx:cursorCanvas.ctx,
|
|
cursorData:cursorCanvas.data,
|
|
active:true,
|
|
stringJS:"",
|
|
text:startText,
|
|
richText:startRichText,
|
|
textLoc:[],
|
|
cursorPos:0,
|
|
cursorMap:[],
|
|
algText:algText,
|
|
leftPoint:leftPoint,
|
|
fontSize:fontSize,
|
|
textColor:textColor,
|
|
textAlign:textAlign,
|
|
transparent:transparent,
|
|
maxChars:maxChars,
|
|
backColor:backColor,
|
|
selectColor:selectColor,
|
|
border:border, // boolean
|
|
borderWidth:borderWidth,
|
|
borderDash:borderDash,
|
|
borderColor:borderColor,
|
|
currBackColor:currBackColor,
|
|
startText:startText,
|
|
startRichText:startRichText,
|
|
startTags:startTags,
|
|
maxLines:maxLines,
|
|
preText:'',
|
|
postText:'',
|
|
vertAlign:vertAlign,
|
|
varSize:varSize,
|
|
selectable:selectable,
|
|
selectPos:[],
|
|
selected:false,
|
|
setBackColor:function(color) {
|
|
this.backColor = color;
|
|
drawMathsInputText(this);
|
|
},
|
|
pointerCanvas:pointerCanvas
|
|
};
|
|
//input.creationTime = (new Date()).getTime();
|
|
mathsInput[pageIndex].push(input);
|
|
currMathsInput = input;
|
|
drawMathsInputText(currMathsInput);
|
|
mathsInputMapCursorPos();
|
|
mathsInputCursorCoords();
|
|
deselectMathsInput();
|
|
if (isTask == false && visible == true) showMathsInput(input);
|
|
return input;
|
|
}
|
|
|
|
function mathsInputFrac(e) {mathsInputElement("['frac', [''], ['']]");}
|
|
function mathsInputPow(e) {mathsInputElement("['power', false, ['']]");}
|
|
function mathsInputSubs(e) {mathsInputElement("['subs', [''], ['']]");}
|
|
function mathsInputRoot(e) {mathsInputElement("['root', [''], ['']]");}
|
|
function mathsInputSqrt(e) {mathsInputElement("['sqrt', ['']]");}
|
|
function mathsInputSin(e) {mathsInputElement("['sin', ['']]");}
|
|
function mathsInputCos(e) {mathsInputElement("['cos', ['']]");}
|
|
function mathsInputTan(e) {mathsInputElement("['tan', ['']]");}
|
|
function mathsInputInvSin(e) {mathsInputElement("['sin-1', ['']]");}
|
|
function mathsInputInvCos(e) {mathsInputElement("['cos-1', ['']]");}
|
|
function mathsInputInvTan(e) {mathsInputElement("['tan-1', ['']]");}
|
|
function mathsInputLn(e) {mathsInputElement("['ln', ['']]");}
|
|
function mathsInputLog(e) {mathsInputElement("['log', ['']]");}
|
|
function mathsInputLogBase(e) {mathsInputElement("['logBase', [''], ['']]");}
|
|
function mathsInputAbs(e) {mathsInputElement("['abs', ['']]");}
|
|
function mathsInputExp(e) {mathsInputElement("['exp', ['']]");}
|
|
function mathsInputSigma1(e) {mathsInputElement("['sigma1', ['']]");}
|
|
function mathsInputSigma2(e) {mathsInputElement("['sigma2', [''], [''], ['']]");}
|
|
function mathsInputInt1(e) {mathsInputElement("['int1', ['']]");}
|
|
function mathsInputInt2(e) {mathsInputElement("['int2', [''], [''], ['']]");}
|
|
function mathsInputVectorArrow(e) {mathsInputElement("['vectorArrow', ['']]");}
|
|
function mathsInputBar(e) {mathsInputElement("['bar', ['']]");}
|
|
function mathsInputHat(e) {mathsInputElement("['hat', ['']]");}
|
|
function mathsInputRecurring(e) {mathsInputElement("['recurring', ['']]");}
|
|
function mathsInputColVector2d(e) {mathsInputElement("['colVector2d', [''], ['']]");}
|
|
function mathsInputColVector3d(e) {mathsInputElement("['colVector3d', [''], [''], ['']]");}
|
|
function mathsInputMixedNum(e) {mathsInputElement("['mixedNum', [''], [''], ['']]");}
|
|
function mathsInputLim(e) {mathsInputElement("['lim', [''], ['']]");}
|
|
|
|
function mathsInputCut() {
|
|
if (currMathsInput.selected == false) return;
|
|
mathsInputCopy();
|
|
currMathsInput.cursorPos = Math.min(currMathsInput.selectPos[0],currMathsInput.selectPos[1]);
|
|
currMathsInput.selPos = [];
|
|
currMathsInput.selected = false;
|
|
deleteSelected();
|
|
removeSelectTags();
|
|
drawMathsInputText(currMathsInput);
|
|
mathsInputMapCursorPos();
|
|
mathsInputCursorCoords();
|
|
}
|
|
function mathsInputCopy() {
|
|
if (currMathsInput.selected == false) return;
|
|
var sel = false;
|
|
clipboard = arrayHandler(clone(currMathsInput.richText));
|
|
|
|
//console.log(clipboard);
|
|
|
|
function arrayHandler(array) {
|
|
for (var l = 0; l < array.length; l++) {
|
|
if (typeof array[l] == 'string') {
|
|
if (l > 0 || array.length == 1 || ['frac','power','pow','subs','subscript','sin','cos','tan','ln','log','logBase','sin-1','cos-1','tan-1','abs','exp','root','sqrt','sigma1','sigma2','int1','int2','recurring','bar','hat','vectorArrow','colVector2d','colVector3d','mixedNum','lim'].indexOf(array[l]) == -1) {
|
|
array[l] = stringHandler(array[l]);
|
|
}
|
|
} else {
|
|
array[l] = arrayHandler(array[l]);
|
|
if (sel == false) {
|
|
array.splice(l,1);
|
|
l--;
|
|
}
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
function stringHandler(string) {
|
|
var delPos = [];
|
|
if (sel == true) delPos[0] = 0;
|
|
var savedTags = '';
|
|
for (var j = 0; j < string.length; j++) {
|
|
var slice = string.slice(j);
|
|
if (slice.indexOf('<<selected:true>>') == 0) {
|
|
delPos[0] = j+17;
|
|
sel = true;
|
|
}
|
|
if (slice.indexOf('<<selected:false>>') == 0) {
|
|
delPos[1] = j;
|
|
sel = false;
|
|
}
|
|
/*if (sel == true && (slice.indexOf('<<font') == 0 || slice.indexOf('<<bold') == 0 || slice.indexOf('<<italic') == 0 || slice.indexOf('<<color') == 0 || slice.indexOf('<<back') == 0)) {
|
|
savedTags += slice.slice(0,slice.indexOf('>>')+2);
|
|
}*/
|
|
}
|
|
if (delPos.length > 0) {
|
|
if (delPos.length == 1) {
|
|
return string.slice(delPos[0])+savedTags;
|
|
} else {
|
|
return string.slice(delPos[0],delPos[1]);
|
|
}
|
|
} else {
|
|
return string;
|
|
}
|
|
}
|
|
}
|
|
function mathsInputPaste() {
|
|
if (typeof clipboard !== 'object' || clipboard == [] || arraysEqual(clipboard,[''])) return;
|
|
var elementString = JSON.stringify(clipboard);
|
|
|
|
if (currMathsInput.selected == true) {
|
|
currMathsInput.cursorPos = Math.min(currMathsInput.selectPos[0],currMathsInput.selectPos[1]);
|
|
currMathsInput.selPos = [];
|
|
currMathsInput.selected = false;
|
|
deleteSelected();
|
|
removeSelectTags();
|
|
drawMathsInputText(currMathsInput);
|
|
mathsInputMapCursorPos();
|
|
mathsInputCursorCoords();
|
|
}
|
|
|
|
var cursorPos = currMathsInput.cursorMap[currMathsInput.cursorPos];
|
|
var parent = currMathsInput.richText;
|
|
for (var aa = 0; aa < cursorPos.length - 1; aa++) {parent = parent[cursorPos[aa]]};
|
|
var pos = cursorPos[cursorPos.length - 1];
|
|
pos = adjustForBreakPoints(pos);
|
|
var parentPos = cursorPos[cursorPos.length - 2];
|
|
var evalString = 'currMathsInput.richText'
|
|
for (var aa = 0; aa < cursorPos.length - 2; aa++) {
|
|
evalString += '[' + cursorPos[aa] + ']';
|
|
}
|
|
var before = parent.slice(0,pos);
|
|
var after = parent.slice(pos);
|
|
|
|
//console.log('before:',before);
|
|
//console.log('after:',after);
|
|
|
|
var newParent = clone(clipboard);
|
|
newParent.unshift(before);
|
|
newParent.push(after);
|
|
|
|
//console.log('newParent:',newParent);
|
|
|
|
eval(evalString+" = newParent;");
|
|
|
|
//console.log('currMathsInput.richText:',currMathsInput.richText);
|
|
|
|
var cursorPosCount = 0;
|
|
arrayHandler(clipboard);
|
|
|
|
function arrayHandler(array) {
|
|
for (var l = 0; l < array.length; l++) {
|
|
if (typeof array[l] == 'string') {
|
|
if (array.length == 1 || ['frac','power','pow','subs','subscript','sin','cos','tan','ln','log','logBase','sin-1','cos-1','tan-1','abs','exp','root','sqrt','sigma1','sigma2','int1','int2','recurring','bar','hat','vectorArrow','colVector2d','colVector3d','mixedNum','lim'].indexOf(array[l]) == -1) {
|
|
cursorPosCount += array[l].length;
|
|
}
|
|
} else {
|
|
arrayHandler(array[l]);
|
|
}
|
|
}
|
|
}
|
|
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos += cursorPosCount;
|
|
mathsInputCursorCoords();
|
|
currMathsInput.preText = '';
|
|
currMathsInput.postText = '';
|
|
}
|
|
|
|
function mathsInputElement(elementString) {
|
|
if (currMathsInput.selected == true) {
|
|
currMathsInput.cursorPos = Math.min(currMathsInput.selectPos[0],currMathsInput.selectPos[1]);
|
|
currMathsInput.selPos = [];
|
|
currMathsInput.selected = false;
|
|
deleteSelected();
|
|
removeSelectTags();
|
|
drawMathsInputText(currMathsInput);
|
|
mathsInputMapCursorPos();
|
|
mathsInputCursorCoords();
|
|
}
|
|
|
|
var cursorPos = currMathsInput.cursorMap[currMathsInput.cursorPos];
|
|
var gparent = currMathsInput.richText;
|
|
for (var aa = 0; aa < cursorPos.length - 2; aa++) {
|
|
gparent = gparent[cursorPos[aa]]
|
|
};
|
|
var parent = gparent[cursorPos[cursorPos.length-2]];
|
|
var parentPos = cursorPos[cursorPos.length-2];
|
|
var pos = cursorPos[cursorPos.length-1];
|
|
pos = adjustForBreakPoints(pos);
|
|
var before = parent.slice(0,pos);
|
|
var after = parent.slice(pos);
|
|
if (!un(currMathsInput.preText) && currMathsInput.preText !== null && currMathsInput.preText !== '') {
|
|
before += currMathsInput.preText;
|
|
}
|
|
if (!un(currMathsInput.postText) && currMathsInput.postText !== null && currMathsInput.postText !== '') {
|
|
after = currMathsInput.postText + after;
|
|
}
|
|
gparent.splice(parentPos,1,before,eval(elementString),after);
|
|
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos++;
|
|
mathsInputCursorCoords();
|
|
currMathsInput.preText = '';
|
|
currMathsInput.postText = '';
|
|
}
|
|
|
|
function mathsInputNewLine() {
|
|
// get cursorPos
|
|
var cursorPos = currMathsInput.cursorMap[currMathsInput.cursorPos];
|
|
|
|
if (typeof currMathsInput.richText[cursorPos[0]] == 'string') {
|
|
var slicePos = cursorPos[1];
|
|
slicePos = adjustForBreakPoints(slicePos);
|
|
// check if there is an align tag
|
|
if (currMathsInput.richText[cursorPos[0]].slice(slicePos).indexOf('<<align:') == 0) {
|
|
slicePos += currMathsInput.richText[cursorPos[0]].slice(slicePos).indexOf('>>')+2;
|
|
}
|
|
slicePos = mathsInputAvoidTagSplit(currMathsInput.richText[cursorPos[0]],slicePos);
|
|
|
|
currMathsInput.richText[cursorPos[0]] = currMathsInput.richText[cursorPos[0]].slice(0,slicePos) + '<<br>>' + currMathsInput.richText[cursorPos[0]].slice(slicePos);
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos += 1;
|
|
mathsInputCursorCoords();
|
|
} else {
|
|
// jump forward from element to next string (if it exists) and insert <<br>>
|
|
var cursorPosShiftCount = 0;
|
|
for (var i = currMathsInput.cursorPos; i < currMathsInput.cursorMap.length; i++) {
|
|
cursorPosShiftCount++;
|
|
// if the next element has been reached
|
|
if (cursorPos[0] < currMathsInput.cursorMap[i][0]) {
|
|
if (typeof currMathsInput.richText[currMathsInput.cursorMap[i][0]] == 'string') {
|
|
cursorPos = currMathsInput.cursorMap[i];
|
|
currMathsInput.richText[currMathsInput.cursorMap[i][0]] = '<<br>>'+currMathsInput.richText[currMathsInput.cursorMap[i][0]];
|
|
break;
|
|
} else {
|
|
// this shouldn't happen?? All elements will be separated by a text string
|
|
}
|
|
} else if (i == currMathsInput.cursorMap.length - 1) {
|
|
currMathsInput.richText.push('<<br>>');
|
|
cursorPosShiftCount += 6;
|
|
|
|
}
|
|
}
|
|
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos += cursorPosShiftCount;
|
|
mathsInputCursorCoords();
|
|
}
|
|
}
|
|
function mathsInputTab(howMany) {
|
|
if (un(howMany)) howMany = 1;
|
|
var ins = "";
|
|
for (var i = 0; i < howMany; i++) {
|
|
ins += String.fromCharCode(0x21F4);
|
|
}
|
|
// get cursorPos
|
|
var cursorPos = currMathsInput.cursorMap[currMathsInput.cursorPos];
|
|
|
|
if (typeof currMathsInput.richText[cursorPos[0]] == 'string') {
|
|
var slicePos = cursorPos[1];
|
|
slicePos = adjustForBreakPoints(slicePos);
|
|
// check if there is an align tag
|
|
if (currMathsInput.richText[cursorPos[0]].slice(slicePos).indexOf('<<align:') == 0) {
|
|
slicePos += currMathsInput.richText[cursorPos[0]].slice(slicePos).indexOf('>>')+2;
|
|
}
|
|
currMathsInput.richText[cursorPos[0]] = currMathsInput.richText[cursorPos[0]].slice(0,slicePos) + ins + currMathsInput.richText[cursorPos[0]].slice(slicePos);
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos += howMany;
|
|
mathsInputCursorCoords();
|
|
} else {
|
|
// jump forward from element to next string (if it exists) and insert <<br>>
|
|
var cursorPosShiftCount = 0;
|
|
for (var i = currMathsInput.cursorPos; i < currMathsInput.cursorMap.length; i++) {
|
|
cursorPosShiftCount++;
|
|
// if the next element has been reached
|
|
if (cursorPos[0] < currMathsInput.cursorMap[i][0]) {
|
|
if (typeof currMathsInput.richText[currMathsInput.cursorMap[i][0]] == 'string') {
|
|
cursorPos = currMathsInput.cursorMap[i];
|
|
currMathsInput.richText[currMathsInput.cursorMap[i][0]] = ins+currMathsInput.richText[currMathsInput.cursorMap[i][0]];
|
|
break;
|
|
} else {
|
|
// this shouldn't happen?? All elements will be separated by a text string
|
|
}
|
|
} else if (i == currMathsInput.cursorMap.length - 1) {
|
|
currMathsInput.richTexts.push(String.fromCharCode(0x21F4));
|
|
cursorPosShiftCount += howMany;
|
|
|
|
}
|
|
}
|
|
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos += cursorPosShiftCount;
|
|
mathsInputCursorCoords();
|
|
}
|
|
}
|
|
function mathsInputLeftArrow(e) {
|
|
if (currMathsInput.cursorPos > 0) {
|
|
currMathsInput.cursorPos--;
|
|
mathsInputCursorCoords();
|
|
} else {
|
|
mathsInputTabPrev();
|
|
}
|
|
}
|
|
function mathsInputRightArrow(e) {
|
|
if (currMathsInput.cursorPos < currMathsInput.cursorMap.length - 1) {
|
|
currMathsInput.cursorPos++;
|
|
mathsInputCursorCoords();
|
|
} else {
|
|
mathsInputTabNext();
|
|
}
|
|
}
|
|
function mathsInputTabPrev() {
|
|
var dx,dy,x,y,currBest1,currBest2;
|
|
for (var i = 0; i < mathsInput[pageIndex].length; i++) {
|
|
if (i == currMathsInputId || mathsInput[pageIndex][i].canvas.parentNode !== container || mathsInput[pageIndex][i].active == false) continue;
|
|
if (mathsInput[pageIndex][i].data[100] < mathsInput[pageIndex][currMathsInputId].data[100] && mathsInput[pageIndex][i].data[101] == mathsInput[pageIndex][currMathsInputId].data[101]) { // if directly to the left
|
|
if (typeof dy == 'undefined') {
|
|
dy = 0;
|
|
dx = mathsInput[pageIndex][currMathsInputId].data[100] - mathsInput[pageIndex][i].data[100];
|
|
currBest1 = i;
|
|
} else if (dy > 0 || (dy == 0 && mathsInput[pageIndex][currMathsInputId].data[100] - mathsInput[pageIndex][i].data[100] < dx)) {
|
|
dy = 0;
|
|
dx = mathsInput[pageIndex][currMathsInputId].data[100] - mathsInput[pageIndex][i].data[100];
|
|
currBest1 = i;
|
|
}
|
|
} else if (mathsInput[pageIndex][i].data[101] < mathsInput[pageIndex][currMathsInputId].data[101]) { // if above
|
|
if (typeof dy == 'undefined') {
|
|
dy = mathsInput[pageIndex][currMathsInputId].data[101] - mathsInput[pageIndex][i].data[101];
|
|
dx = mathsInput[pageIndex][currMathsInputId].data[100] - mathsInput[pageIndex][i].data[100];
|
|
currBest1 = i;
|
|
} else if (dy > mathsInput[pageIndex][currMathsInputId].data[101] - mathsInput[pageIndex][i].data[101] || (dy == mathsInput[pageIndex][currMathsInputId].data[101] - mathsInput[pageIndex][i].data[101] && mathsInput[pageIndex][currMathsInputId].data[100] - mathsInput[pageIndex][i].data[100] < dx)) {
|
|
dy = mathsInput[pageIndex][currMathsInputId].data[101] - mathsInput[pageIndex][i].data[101];
|
|
dx = mathsInput[pageIndex][currMathsInputId].data[100] - mathsInput[pageIndex][i].data[100];
|
|
currBest1 = i;
|
|
}
|
|
|
|
} else if ((mathsInput[pageIndex][i].data[100] > mathsInput[pageIndex][currMathsInputId].data[100] && mathsInput[pageIndex][i].data[101] == mathsInput[pageIndex][currMathsInputId].data[101]) || mathsInput[pageIndex][i].data[101] > mathsInput[pageIndex][currMathsInputId].data[101]) { // if directly to the right or below
|
|
if (typeof y == 'undefined') {
|
|
y = mathsInput[pageIndex][i].data[101];
|
|
x = mathsInput[pageIndex][i].data[100];
|
|
currBest2 = i;
|
|
} else if (mathsInput[pageIndex][i].data[101] > y || (mathsInput[pageIndex][i].data[101] == y && mathsInput[pageIndex][i].data[100] > x)) {
|
|
y = mathsInput[pageIndex][i].data[101];
|
|
x = mathsInput[pageIndex][i].data[100];
|
|
currBest2 = i;
|
|
}
|
|
}
|
|
}
|
|
if (typeof currBest1 !== 'undefined') {
|
|
currMathsInput.preText = '';
|
|
currMathsInput.postText = '';
|
|
deselectMathsInput(mathsInput[pageIndex][currBest1],true);
|
|
startMathsInput(mathsInput[pageIndex][currBest1]);
|
|
currMathsInput.cursorPos = currMathsInput.cursorMap.length - 1;
|
|
mathsInputCursorCoords();
|
|
} else if (typeof currBest2 !== 'undefined') {
|
|
currMathsInput.preText = '';
|
|
currMathsInput.postText = '';
|
|
deselectMathsInput(mathsInput[pageIndex][currBest2],true);
|
|
startMathsInput(mathsInput[pageIndex][currBest2]);
|
|
currMathsInput.cursorPos = 0;
|
|
mathsInputCursorCoords();
|
|
}
|
|
}
|
|
function mathsInputTabNext() {
|
|
var index = mathsInput[pageIndex].indexOf(currMathsInput);
|
|
if (index > -1) {
|
|
var newIndex = (index+1) % mathsInput[pageIndex].length;
|
|
currMathsInput.preText = '';
|
|
currMathsInput.postText = '';
|
|
deselectMathsInput(mathsInput[pageIndex][newIndex],true);
|
|
startMathsInput(mathsInput[pageIndex][newIndex]);
|
|
currMathsInput.cursorPos = currMathsInput.cursorMap.length - 1;
|
|
mathsInputCursorCoords();
|
|
}
|
|
return;
|
|
|
|
/*var dx,dy,x,y,currBest1,currBest2;
|
|
for (var i = 0; i < mathsInput[pageIndex].length; i++) {
|
|
if (i == currMathsInputId || mathsInput[pageIndex][i].canvas.parentNode !== container || mathsInput[pageIndex][i].active == false) continue;
|
|
if (mathsInput[pageIndex][i].data[100] > mathsInput[pageIndex][currMathsInputId].data[100] && mathsInput[pageIndex][i].data[101] == mathsInput[pageIndex][currMathsInputId].data[101]) { // if directly to the right
|
|
if (typeof dy == 'undefined') {
|
|
dy = 0;
|
|
dx = mathsInput[pageIndex][i].data[100] - mathsInput[pageIndex][currMathsInputId].data[100];
|
|
currBest1 = i;
|
|
} else if (dy > 0 || (dy == 0 && mathsInput[pageIndex][i].data[100] - mathsInput[pageIndex][currMathsInputId].data[100] < dx)) {
|
|
dy = 0;
|
|
dx = mathsInput[pageIndex][i].data[100] - mathsInput[pageIndex][currMathsInputId].data[100];
|
|
currBest1 = i;
|
|
}
|
|
} else if (mathsInput[pageIndex][i].data[101] > mathsInput[pageIndex][currMathsInputId].data[101]) { // if below
|
|
if (typeof dy == 'undefined') {
|
|
dy = mathsInput[pageIndex][i].data[101] - mathsInput[pageIndex][currMathsInputId].data[101];
|
|
dx = mathsInput[pageIndex][i].data[100] - mathsInput[pageIndex][currMathsInputId].data[100];
|
|
currBest1 = i;
|
|
} else if (dy > mathsInput[pageIndex][i].data[101] - mathsInput[pageIndex][currMathsInputId].data[101] || (dy == mathsInput[pageIndex][i].data[101] - mathsInput[pageIndex][currMathsInputId].data[101] && mathsInput[pageIndex][i].data[100] - mathsInput[pageIndex][currMathsInputId].data[100] < dx)) {
|
|
dy = mathsInput[pageIndex][i].data[101] - mathsInput[pageIndex][currMathsInputId].data[101];
|
|
dx = mathsInput[pageIndex][i].data[100] - mathsInput[pageIndex][currMathsInputId].data[100];
|
|
currBest1 = i;
|
|
}
|
|
|
|
} else if ((mathsInput[pageIndex][i].data[100] < mathsInput[pageIndex][currMathsInputId].data[100] && mathsInput[pageIndex][i].data[101] == mathsInput[pageIndex][currMathsInputId].data[101]) || mathsInput[pageIndex][i].data[101] < mathsInput[pageIndex][currMathsInputId].data[101]) { // if directly to the left or above
|
|
if (typeof y == 'undefined') {
|
|
y = mathsInput[pageIndex][i].data[101];
|
|
x = mathsInput[pageIndex][i].data[100];
|
|
currBest2 = i;
|
|
} else if (mathsInput[pageIndex][i].data[101] < y || (mathsInput[pageIndex][i].data[101] == y && mathsInput[pageIndex][i].data[100] < x)) {
|
|
y = mathsInput[pageIndex][i].data[101];
|
|
x = mathsInput[pageIndex][i].data[100];
|
|
currBest2 = i;
|
|
}
|
|
}
|
|
}
|
|
if (typeof currBest1 !== 'undefined') {
|
|
currMathsInput.preText = '';
|
|
currMathsInput.postText = '';
|
|
deselectMathsInput(mathsInput[pageIndex][currBest1],true);
|
|
startMathsInput(mathsInput[pageIndex][currBest1]);
|
|
currMathsInput.cursorPos = currMathsInput.cursorMap.length - 1;
|
|
mathsInputCursorCoords();
|
|
} else if (typeof currBest2 !== 'undefined') {
|
|
currMathsInput.preText = '';
|
|
currMathsInput.postText = '';
|
|
deselectMathsInput(mathsInput[pageIndex][currBest2],true);
|
|
startMathsInput(mathsInput[pageIndex][currBest2]);
|
|
currMathsInput.cursorPos = 0;
|
|
mathsInputCursorCoords();
|
|
}*/
|
|
}
|
|
|
|
function mathsInputAvoidTagSplit(txt,slicePos) {
|
|
// check that a tag is not being split - if so adjust slicePos
|
|
var leftText = txt.slice(0,slicePos);
|
|
var rightText = txt.slice(slicePos);
|
|
//console.clear();
|
|
//console.log(txt,slicePos);
|
|
//console.log(leftText);
|
|
//console.log(rightText);
|
|
var tagLeft = false;
|
|
var tagLeftCount = 0;
|
|
for (var i = 0; i < leftText.length; i++) {
|
|
tagLeftCount++;
|
|
//console.log('left '+i+':',leftText.slice(leftText.length - i));
|
|
if (leftText.slice(leftText.length - i).indexOf('>>') == 0) break;
|
|
if (leftText.slice(leftText.length - i).indexOf('<<') == 0) {
|
|
tagLeft = true;
|
|
break;
|
|
}
|
|
}
|
|
var tagRight = false;
|
|
var tagRightCount = 0;
|
|
for (var j = 0; j < rightText.length; j++) {
|
|
tagRightCount++;
|
|
//console.log('right '+j+':',rightText.slice(j));
|
|
if (rightText.slice(j).indexOf('<<') == 0) break;
|
|
if (rightText.slice(j).indexOf('>>') == 0) {
|
|
tagRight = true;
|
|
break;
|
|
}
|
|
}
|
|
//console.log(tagLeft,tagRight,tagLeftCount,tagRightCount);
|
|
if (tagLeft == true && tagRight == true) {
|
|
if (tagLeftCount <= tagRightCount) {
|
|
slicePos -= tagLeftCount;
|
|
} else {
|
|
slicePos += tagRightCount;
|
|
}
|
|
}
|
|
// test if '<',slicePos,'<' or '>',slicePos,'>'
|
|
if (leftText.slice(-1) == '<' && rightText.slice(0,1) == '<' && rightText.slice(0,2) !== '<<') slicePos--;
|
|
if (leftText.slice(-1) == '>' && leftText.slice(-2) !== '>>' && rightText.slice(0,1) == '>') slicePos++;
|
|
|
|
return slicePos;
|
|
}
|
|
|
|
function startMathsInput(e,startCursorPos) {
|
|
deselectMathsInput(e,true);
|
|
window.addEventListener('keydown', hardKeyMathsInput, false);
|
|
canvas.addEventListener('mousedown', endMathsInput, false); // clicking anywhere on the canvas will end the input
|
|
canvas.addEventListener('touchstart', endMathsInput, false); // touching anywhere on the canvas will end the input
|
|
/*// clicking a holder button will end the input
|
|
if (typeof holderButton !== 'undefined') {
|
|
for (i = 0; i < 3; i++) {
|
|
holderButton[i].addEventListener('mousedown', endMathsInput, false);
|
|
holderButton[i].addEventListener('touchstart', endMathsInput, false);
|
|
}
|
|
}
|
|
for (i = 0; i < taskObject[pageIndex].length; i++) { // clicking any other object will also end the input
|
|
if (endInputExceptions.indexOf(taskObject[pageIndex][i]) == -1) {
|
|
taskObject[pageIndex][i].addEventListener('mousedown', endMathsInput, false);
|
|
taskObject[pageIndex][i].addEventListener('touchstart', endMathsInput, false);
|
|
}
|
|
}*/
|
|
if (e.target) {
|
|
var inputCanvas = e.target;
|
|
} else {
|
|
var inputCanvas = e;
|
|
};
|
|
for (i = 0; i < mathsInput[pageIndex].length; i++) {
|
|
if (mathsInput[pageIndex][i].cursorCanvas == inputCanvas || mathsInput[pageIndex][i].canvas == inputCanvas || mathsInput[pageIndex][i] == inputCanvas) {
|
|
currMathsInput = mathsInput[pageIndex][i];
|
|
currMathsInputId = i;
|
|
}
|
|
}
|
|
if (currMathsInput.transparent == false && currMathsInput.selectColor !== 'none') {
|
|
currMathsInput.canvas.style.backgroundColor = "#FCF";
|
|
} else if (currMathsInput.transparent == false || currMathsInput.selectColor == 'none') {
|
|
currMathsInput.canvas.style.backgroundColor = "#transparent";
|
|
}
|
|
inputState = true; // allows the onscreen keys to function
|
|
var closestPos = getClosestTextPos();
|
|
//console.log(currMathsInput,closestPos,currMathsInput.selectable,startCursorPos);
|
|
if (currMathsInput.selectable == true && typeof startCursorPos == 'undefined') {
|
|
currMathsInput.selectPos = [closestPos,closestPos];
|
|
setSelectPositions();
|
|
drawMathsInputText(currMathsInput);
|
|
mathsInputMapCursorPos();
|
|
if (typeof currMathsInput.pointerCanvas !== 'object') {
|
|
addListenerMove(currMathsInput.cursorCanvas,selectTextMove);
|
|
addListenerEnd(currMathsInput.cursorCanvas,selectTextStop);
|
|
}
|
|
} else {
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos = startCursorPos || Number(closestPos) || 0;
|
|
//console.log(currMathsInput,currMathsInput.cursorPos,currMathsInput.cursorMap[currMathsInput.cursorPos],currMathsInput.textLoc);
|
|
mathsInputCursorCoords();
|
|
updateKeyboardCurrFont();
|
|
showKeyboard2(true);
|
|
}
|
|
if (!un(currMathsInput.markPos)) {
|
|
currMathsInput.markctx.clearRect(currMathsInput.markPos[0]-5,currMathsInput.markPos[1]-5,currMathsInput.markPos[2]+10,currMathsInput.markPos[3]+10);
|
|
}
|
|
//shiftOn = false;
|
|
//ctrlOn = false;
|
|
//altOn = false;
|
|
if (!un(window.textMenu) && typeof textMenu.show == 'function' && textMenu.showOnStartInput == true) {
|
|
textMenu.update();
|
|
textMenu.show();
|
|
}
|
|
}
|
|
function selectTextMove(e) {
|
|
updateMouse(e);
|
|
var closestPos = getClosestTextPos();
|
|
//console.log(closestPos);
|
|
if (currMathsInput.selectPos[1] !== closestPos) {
|
|
currMathsInput.selectPos[1] = closestPos;
|
|
//console.log(currMathsInput.selectPos);
|
|
currMathsInput.selected = true;
|
|
setSelectPositions();
|
|
drawMathsInputText(currMathsInput);
|
|
mathsInputMapCursorPos();
|
|
}
|
|
console.log(currMathsInput.selectPos);
|
|
//console.log('selectTextMove',currMathsInput.selected);
|
|
}
|
|
function selectTextStop(e) {
|
|
//console.log(currMathsInput.selectPos);
|
|
removeListenerMove(currMathsInput.cursorCanvas,selectTextMove);
|
|
removeListenerEnd(currMathsInput.cursorCanvas,selectTextStop);
|
|
if (currMathsInput.selectPos[0] == currMathsInput.selectPos[1]) {
|
|
currMathsInput.cursorPos = currMathsInput.selectPos[0];
|
|
currMathsInput.selectPos = [];
|
|
currMathsInput.selected = false;
|
|
setSelectPositions();
|
|
mathsInputMapCursorPos();
|
|
mathsInputCursorCoords();
|
|
}
|
|
updateKeyboardCurrFont();
|
|
showKeyboard2(true);
|
|
}
|
|
function getClosestTextPos(mathsInput) {
|
|
if (!mathsInput) mathsInput = currMathsInput;
|
|
// search through text character locations for a mouse hit test
|
|
var mousePos = [mouse.x-mathsInput.data[100],mouse.y-mathsInput.data[101]];
|
|
//console.log(mathsInput);
|
|
if (typeof mathsInput.cursorMap == 'undefined') {
|
|
mathsInputMapCursorPos();
|
|
}
|
|
var map = mathsInput.cursorMap;
|
|
var closestPos = 0;
|
|
var closestDist;
|
|
var vertDist;
|
|
var closestVertDist;
|
|
//console.log('getClosestTextPos()');
|
|
//console.clear();
|
|
for (var pos = 0; pos < map.length; pos++) {
|
|
var loc = mathsInput.textLoc;
|
|
for (var aa = 0; aa < map[pos].length; aa++) {
|
|
loc = loc[map[pos][aa]];
|
|
};
|
|
|
|
/*
|
|
var ctx = mathsInput.ctx;
|
|
ctx.strokeStyle = '#F0F';
|
|
ctx.beginPath();
|
|
ctx.moveTo(loc.left,loc.top);
|
|
ctx.lineTo(loc.left,loc.top+loc.height);
|
|
ctx.stroke();
|
|
*/
|
|
|
|
if (!loc) continue;
|
|
|
|
if (pos == 0) {
|
|
closestDist = distancePointToLineSegment(mousePos,[loc.left,loc.top],[loc.left,loc.top+loc.height]);
|
|
closestPos = pos;
|
|
vertDist = Math.min(Math.abs(mousePos[1]-loc.top),Math.abs(mousePos[1]-(loc.top+loc.height)));
|
|
if (mousePos[1] >= loc.top && mousePos[1] <= loc.top + loc.height) vertDist = 0;
|
|
closestVertDist = vertDist;
|
|
} else {
|
|
var newDist = distancePointToLineSegment(mousePos,[loc.left,loc.top],[loc.left,loc.top+loc.height]);
|
|
var newVertDist = Math.min(Math.abs(mousePos[1]-loc.top),Math.abs(mousePos[1]-(loc.top+loc.height)));
|
|
if (mousePos[1] >= loc.top && mousePos[1] <= loc.top + loc.height) newVertDist = 0;
|
|
if (newVertDist < closestVertDist || (newVertDist == closestVertDist && newDist < closestDist)) {
|
|
closestVertDist = newVertDist;
|
|
closestDist = newDist;
|
|
closestPos = pos;
|
|
}
|
|
}
|
|
|
|
//console.log(pos,loc.left,newDist,closestDist,closestPos)
|
|
}
|
|
|
|
/*
|
|
ctx.beginPath();
|
|
ctx.moveTo(mousePos[0]-3,mousePos[1]-3);
|
|
ctx.lineTo(mousePos[0]+3,mousePos[1]+3);
|
|
ctx.moveTo(mousePos[0]-3,mousePos[1]+3);
|
|
ctx.lineTo(mousePos[0]+3,mousePos[1]-3);
|
|
ctx.stroke();
|
|
*/
|
|
//console.log(closestPos);
|
|
if (isNaN(closestPos) || typeof closestPos == 'undefined' || closestPos == null) {
|
|
closestPos = 0;
|
|
}
|
|
return closestPos;
|
|
}
|
|
function endMathsInput(e) {
|
|
if (!un(e) && !un(keyboardButton1) && !un(keyboardButton1[pageIndex]) && e.target == keyboardButton1[pageIndex]) return;
|
|
if (!un(e) && !un(keyboardButton2) && !un(keyboardButton2[pageIndex]) && e.target == keyboardButton2[pageIndex]) return;
|
|
if (un(currMathsInput)) return;
|
|
if (currMathsInput.selected == true) {
|
|
removeSelectTags();
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos = Math.min(currMathsInput.selectPos[0],currMathsInput.selectPos[1]);
|
|
currMathsInput.selectPos = [];
|
|
mathsInputCursorCoords();
|
|
currMathsInput.selected = false;
|
|
removeSelectTags();
|
|
}
|
|
deselectMathsInput(e);
|
|
|
|
if (typeof currMathsInput.onInputEnd == 'function') {
|
|
currMathsInput.onInputEnd(e);
|
|
}
|
|
}
|
|
function deselectMathsInput(e,diffInput) {
|
|
if (un(currMathsInput)) return;
|
|
currMathsInput.preText = '';
|
|
currMathsInput.postText = '';
|
|
if (currMathsInput.selected == true) {
|
|
removeSelectTags();
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos = Math.min(currMathsInput.selectPos[0],currMathsInput.selectPos[1]);
|
|
currMathsInput.selectPos = [];
|
|
mathsInputCursorCoords();
|
|
currMathsInput.selected = false;
|
|
removeSelectTags();
|
|
}
|
|
// test if the deselection is caused by a new input
|
|
var diffInputTest = -1;
|
|
if (typeof e == 'object' && e && typeof e.target == 'object' && e.target !== currMathsInput.canvas && !un(mathsInput[pageIndex])) {
|
|
for (var i = 0; i < mathsInput[pageIndex].length; i++) {
|
|
if (mathsInput[pageIndex][i].cursorCanvas == e.target) {
|
|
if (currMathsInput.canvas == e.target) {
|
|
return; // indicates the currently active mathsInput has been reclicked - do nothing
|
|
} else {
|
|
diffInputTest = i;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((typeof diffInput !== 'undefined' && diffInput == true) || diffInputTest > -1) {
|
|
|
|
} else {
|
|
hideKeyboard2(true);
|
|
inputState = false;
|
|
// remove event listeners for mathsInput
|
|
window.removeEventListener('keydown', hardKeyMathsInput, false);
|
|
canvas.removeEventListener('mousedown', endMathsInput, false);
|
|
canvas.removeEventListener('touchstart', endMathsInput, false);
|
|
}
|
|
|
|
//currMathsInput.currBackColor = currMathsInput.backColor;
|
|
/*
|
|
currMathsInput.ctx.clearRect(0, 0, currMathsInput.data[2], currMathsInput.data[3]);
|
|
if (currMathsInput.transparent == false && currMathsInput.backColor !== 'none') {
|
|
currMathsInput.ctx.fillStyle = currMathsInput.backColor || '#FFF';
|
|
}
|
|
*/
|
|
|
|
currMathsInput.canvas.style.backgroundColor = currMathsInput.backColor || 'transparent';
|
|
if (currMathsInput.backColor == 'none') {
|
|
currMathsInput.canvas.style.backgroundColor = 'transparent'
|
|
}
|
|
|
|
clearCorrectingInterval(mathsInputCursorBlinkInterval);
|
|
inputCursorState = false
|
|
blinking = false;
|
|
|
|
currMathsInput.cursorctx.clearRect(0,0,1200,700);
|
|
|
|
if ((typeof diffInput !== 'undefined' && diffInput == true) || diffInputTest > -1) {
|
|
if (typeof currMathsInput.onInputEnd == 'function') {
|
|
currMathsInput.onInputEnd();
|
|
}
|
|
} else {
|
|
if (!un(window.textMenu)) {
|
|
if (typeof textMenu.show == 'function' && textMenu.showOnStartInput == true) {
|
|
textMenu.hide();
|
|
}
|
|
}
|
|
}
|
|
if (typeof holderButton !== 'undefined') {
|
|
for (var i = 0; i < 3; i++) {
|
|
holderButton[i].removeEventListener('mousedown', endMathsInput, false);
|
|
holderButton[i].removeEventListener('mousedown', endMathsInput, false);
|
|
}
|
|
}
|
|
/*var startAt = 0;
|
|
if (taskKey[pageIndex]) {startAt = taskKey[pageIndex].length}
|
|
function listenerForI(i) {
|
|
taskObject[pageIndex][i].removeEventListener('mousedown', endMathsInput, false);
|
|
taskObject[pageIndex][i].removeEventListener('touchstart', endMathsInput, false);
|
|
}
|
|
if (taskObject[pageIndex]) {
|
|
for (var i = startAt; i < taskObject[pageIndex].length; i++) { // clicking any other object will also end the input
|
|
listenerForI(i); //'scopes' the variable i
|
|
}
|
|
}*/
|
|
|
|
}
|
|
|
|
function setSelectPositions() {
|
|
// check for a need to adjust each selectPos
|
|
|
|
var selPos1 = clone(currMathsInput.cursorMap[currMathsInput.selectPos[0]]);
|
|
if (typeof selPos1 !== 'undefined') {
|
|
var txt = clone(currMathsInput.richText);
|
|
for (var i = 0; i < selPos1.length - 1; i++) {txt = txt[selPos1[i]]};
|
|
var txtSlice = txt.slice(0,selPos1[selPos1.length-1]);
|
|
if (txtSlice.indexOf('<<selected:true>>') > -1) {
|
|
selPos1[selPos1.length-1] -= 17;
|
|
}
|
|
if (txtSlice.indexOf('<<selected:false>>') > -1) {
|
|
selPos1[selPos1.length-1] -= 18;
|
|
}
|
|
}
|
|
|
|
var selPos2 = clone(currMathsInput.cursorMap[currMathsInput.selectPos[1]]);
|
|
if (typeof selPos2 !== 'undefined') {
|
|
var txt = clone(currMathsInput.richText);
|
|
for (var i = 0; i < selPos2.length - 1; i++) {txt = txt[selPos2[i]]};
|
|
var txtSlice = txt.slice(0,selPos2[selPos2.length-1]);
|
|
if (txtSlice.indexOf('<<selected:true>>') > -1) {
|
|
selPos2[selPos2.length-1] -= 17;
|
|
}
|
|
if (txtSlice.indexOf('<<selected:false>>') > -1) {
|
|
selPos2[selPos2.length-1] -= 18;
|
|
}
|
|
}
|
|
|
|
removeSelectTags();
|
|
|
|
if (arraysEqual(currMathsInput.selectPos,[]) == false) {
|
|
if (currMathsInput.selectPos[0] == currMathsInput.selectPos[1]) {
|
|
insertTag('<<selected:true>><<selected:false>>',selPos1);
|
|
} else if (currMathsInput.selectPos[0] > currMathsInput.selectPos[1]) {
|
|
insertTag('<<selected:false>>',selPos1);
|
|
insertTag('<<selected:true>>',selPos2);
|
|
} else if (currMathsInput.selectPos[0] < currMathsInput.selectPos[1]) {
|
|
insertTag('<<selected:false>>',selPos2);
|
|
insertTag('<<selected:true>>',selPos1);
|
|
}
|
|
}
|
|
|
|
function insertTag(insertion,cursorPos) {
|
|
// get the relevant string from currMathsInput.richText
|
|
var text = currMathsInput.richText;
|
|
for (var aa = 0; aa < cursorPos.length - 1; aa++) {
|
|
text = text[cursorPos[aa]];
|
|
}
|
|
// pos is position of cursor
|
|
var pos = cursorPos[cursorPos.length - 1];
|
|
|
|
// adjust pos to account for breakPoints
|
|
if (typeof currMathsInput.breakPoints == 'object') {
|
|
for (var k = 0; k < currMathsInput.breakPoints.length - 1; k++) {
|
|
var breakPoint = currMathsInput.allMap[currMathsInput.breakPoints[k]];
|
|
if (breakPoint[0] == cursorPos[0] && breakPoint[1] < cursorPos[1]) {
|
|
pos--;
|
|
}
|
|
}
|
|
}
|
|
// check that a tag is not being split - if so adjust pos
|
|
var leftText = text.slice(0,pos);
|
|
var rightText = text.slice(pos);
|
|
var tagLeft = false;
|
|
var tagLeftCount = 0;
|
|
for (var i = 0; i < leftText.length; i++) {
|
|
tagLeftCount++;
|
|
if (leftText.slice(leftText.length - i).indexOf('>>') == 0) break;
|
|
if (leftText.slice(leftText.length - i).indexOf('<<') == 0) {
|
|
tagLeft = true;
|
|
break;
|
|
}
|
|
}
|
|
var tagRight = false;
|
|
var tagRightCount = 0;
|
|
for (var j = 0; j < rightText.length; j++) {
|
|
tagRightCount++;
|
|
if (rightText.slice(j).indexOf('<<') == 0) break;
|
|
if (rightText.slice(j).indexOf('>>') == 0) {
|
|
tagRight = true;
|
|
break;
|
|
}
|
|
}
|
|
if (tagLeft == true && tagRight == true) {
|
|
if (tagLeftCount <= tagRightCount) {
|
|
pos -= tagLeftCount;
|
|
} else {
|
|
pos += tagRightCount;
|
|
}
|
|
}
|
|
var leftText = text.slice(0,pos);
|
|
var rightText = text.slice(pos);
|
|
if (leftText.slice(-1) == '<' && rightText.slice(0,1) == '<' && rightText.slice(0,2) !== '<<') pos--;
|
|
if (leftText.slice(-1) == '>' && leftText.slice(-2) !== '>>' && rightText.slice(0,1) == '>') pos++;
|
|
var textBefore = text.slice(0,pos);
|
|
var textAfter = text.slice(pos);
|
|
|
|
text = textBefore + insertion + textAfter;
|
|
// replace the string
|
|
var evalString = 'currMathsInput.richText'
|
|
for (aa = 0; aa < cursorPos.length - 1; aa++) {
|
|
evalString += '[' + cursorPos[aa] + ']';
|
|
}
|
|
eval(evalString + ' = text;');
|
|
}
|
|
}
|
|
function removeSelectTags() {
|
|
var map1;
|
|
var map2;
|
|
var pos = [];
|
|
function arrayHandler(array) {
|
|
pos.push(0);
|
|
for (var l = array.length - 1; l >= 0; l--) {
|
|
pos[pos.length-1] = l;
|
|
if (typeof array[l] == 'string') {
|
|
array[l] = stringHandler(array[l]);
|
|
} else {
|
|
array[l] = arrayHandler(array[l]);
|
|
}
|
|
}
|
|
pos.pop();
|
|
return array;
|
|
}
|
|
function stringHandler(string) {
|
|
//console.log(string,JSON.stringify(pos));
|
|
for (var j = string.length - 1; j >= 0; j--) {
|
|
var slice = string.slice(j);
|
|
if (slice.indexOf('<<selected:false>>') == 0) {
|
|
string = string.slice(0,j)+string.slice(j+slice.indexOf('>>')+2);
|
|
if (typeof map1 !== 'undefined' && arraysEqual(pos,map1) == true && map2 > j) {
|
|
map2 = Math.max(0,map2-18);
|
|
}
|
|
}
|
|
if (slice.indexOf('<<selected:true>>') == 0) {
|
|
string = string.slice(0,j)+string.slice(j+slice.indexOf('>>')+2);
|
|
if (typeof map1 !== 'undefined' && arraysEqual(pos,map1) == true && map2 > j) {
|
|
map2 = Math.max(0,map2-17);
|
|
}
|
|
}
|
|
}
|
|
return string;
|
|
}
|
|
|
|
//console.log(JSON.stringify(currMathsInput.cursorMap[currMathsInput.cursorPos]));
|
|
if (typeof currMathsInput.cursorPos == 'number') {
|
|
map1 = currMathsInput.cursorMap[currMathsInput.cursorPos];
|
|
if (typeof map1 !== 'undefined') {
|
|
map2 = map1[map1.length-1];
|
|
map1 = map1.slice(0,-1);
|
|
//console.log(JSON.stringify(map1),map2);
|
|
}
|
|
}
|
|
|
|
currMathsInput.richText = arrayHandler(currMathsInput.richText);
|
|
|
|
//console.log('---',map2);
|
|
if (typeof map2 !== 'undefined') {
|
|
currMathsInput.cursorMap[currMathsInput.cursorPos][currMathsInput.cursorMap[currMathsInput.cursorPos].length-1] = map2;
|
|
}
|
|
// adjust cursorPos if necessary
|
|
|
|
}
|
|
function removeSelectTagsFromArray(textArray) {
|
|
var map1;
|
|
var map2;
|
|
var pos = [];
|
|
function arrayHandler(array) {
|
|
pos.push(0);
|
|
for (var l = array.length - 1; l >= 0; l--) {
|
|
pos[pos.length-1] = l;
|
|
if (typeof array[l] == 'string') {
|
|
array[l] = stringHandler(array[l]);
|
|
} else {
|
|
array[l] = arrayHandler(array[l]);
|
|
}
|
|
}
|
|
pos.pop();
|
|
return array;
|
|
}
|
|
function stringHandler(string) {
|
|
//console.log(string,JSON.stringify(pos));
|
|
for (var j = string.length - 1; j >= 0; j--) {
|
|
var slice = string.slice(j);
|
|
if (slice.indexOf('<<selected:false>>') == 0) {
|
|
string = string.slice(0,j)+string.slice(j+slice.indexOf('>>')+2);
|
|
if (typeof map1 !== 'undefined' && arraysEqual(pos,map1) == true && map2 > j) {
|
|
map2 = Math.max(0,map2-18);
|
|
}
|
|
}
|
|
if (slice.indexOf('<<selected:true>>') == 0) {
|
|
string = string.slice(0,j)+string.slice(j+slice.indexOf('>>')+2);
|
|
if (typeof map1 !== 'undefined' && arraysEqual(pos,map1) == true && map2 > j) {
|
|
map2 = Math.max(0,map2-17);
|
|
}
|
|
}
|
|
}
|
|
return string;
|
|
}
|
|
|
|
return arrayHandler(textArray);
|
|
}
|
|
function deleteSelected() {
|
|
var sel = false;
|
|
currMathsInput.richText = arrayHandler(currMathsInput.richText);
|
|
|
|
function arrayHandler(array) {
|
|
for (var l = 0; l < array.length; l++) {
|
|
if (typeof array[l] == 'string') {
|
|
if (l > 0 || array.length == 1 || ['frac','power','pow','subs','subscript','sin','cos','tan','ln','log','logBase','sin-1','cos-1','tan-1','abs','exp','root','sqrt','sigma1','sigma2','int1','int2','recurring','bar','hat','vectorArrow','colVector2d','colVector3d','mixedNum','lim'].indexOf(array[l]) == -1) {
|
|
array[l] = stringHandler(array[l]);
|
|
}
|
|
} else {
|
|
var preSel = false;
|
|
if (sel == true) {preSel = true};
|
|
array[l] = arrayHandler(array[l]);
|
|
if (sel == true && preSel == true) {
|
|
array.splice(l,1);
|
|
l--;
|
|
}
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
function stringHandler(string) {
|
|
var delPos = [];
|
|
if (sel == true) delPos[0] = 0;
|
|
var savedTags = '';
|
|
for (var j = 0; j < string.length; j++) {
|
|
var slice = string.slice(j);
|
|
if (slice.indexOf('<<selected:true>>') == 0) {
|
|
delPos[0] = j;
|
|
sel = true;
|
|
}
|
|
if (slice.indexOf('<<selected:false>>') == 0) {
|
|
delPos[1] = j + 18;
|
|
sel = false;
|
|
}
|
|
if (sel == true && (slice.indexOf('<<font') == 0 || slice.indexOf('<<bold') == 0 || slice.indexOf('<<italic') == 0 || slice.indexOf('<<color') == 0 || slice.indexOf('<<back') == 0)) {
|
|
savedTags += slice.slice(0,slice.indexOf('>>')+2);
|
|
}
|
|
}
|
|
if (delPos.length > 0) {
|
|
if (delPos.length == 1) {
|
|
return string.slice(0,delPos[0])+savedTags;
|
|
} else {
|
|
return string.slice(0,delPos[0])+savedTags+string.slice(delPos[1]);
|
|
}
|
|
} else {
|
|
return string;
|
|
}
|
|
}
|
|
}
|
|
|
|
function mathsInputMapCursorPos() { // (re-)builds cursor map
|
|
currMathsInput.richText = reduceTags(currMathsInput.richText);
|
|
currMathsInput.richText = combineSpacesCursor(currMathsInput.richText);
|
|
|
|
// create new cursor map
|
|
currMathsInput.textLoc = [];
|
|
drawMathsInputText(currMathsInput);
|
|
currMathsInput.cursorMap = mapArray(currMathsInput.textLoc,false);
|
|
|
|
// create new allMap - this includes all markup tag characters
|
|
currMathsInput.allMap = mapArray(currMathsInput.textLoc,true);
|
|
|
|
// move cursor positions in cursorMap from end to beginning of markup tags (except for beginning)
|
|
var cursorMap = currMathsInput.cursorMap;
|
|
|
|
//console.log(currMathsInput.cursorPos,JSON.stringify(cursorMap));
|
|
|
|
for (var i = 1; i < cursorMap.length; i++) {
|
|
|
|
// get text element
|
|
var richText = currMathsInput.richText;
|
|
for (var j = 0; j < cursorMap[i].length - 1; j++) richText = richText[cursorMap[i][j]];
|
|
|
|
// char is position of cursor
|
|
var char = cursorMap[i][cursorMap[i].length-1];
|
|
|
|
// adjust char to account for breakPoints
|
|
if (typeof currMathsInput.breakPoints == 'object') {
|
|
for (var k = 0; k < currMathsInput.breakPoints.length - 1; k++) {
|
|
var breakPoint = currMathsInput.allMap[currMathsInput.breakPoints[k]];
|
|
if (breakPoint[0] == cursorMap[i][0] && breakPoint[1] < cursorMap[i][1]) {
|
|
char--;
|
|
}
|
|
}
|
|
}
|
|
|
|
// if proceeded by a tag
|
|
if (richText.slice(char-2).indexOf('>>') == 0 && richText.slice(char-6).indexOf('<<br>>') !== 0) {
|
|
|
|
// get text to the left of char
|
|
var leftText = richText.slice(0,char);
|
|
|
|
// get tagCharCount to the left of char
|
|
var tagCharCount = 0;
|
|
for (var j = 0; j < leftText.length; j++) {
|
|
if (richText.slice(char-j,char).indexOf('<<') == 0 && (leftText.slice(char-j-2,char).indexOf('>>') !== 0 || leftText.slice(char-j-6,char).indexOf('<<br>>') == 0)) {
|
|
tagCharCount = j;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// check that it's not the very beginning
|
|
if (cursorMap[i][0] == 0 && cursorMap[i][1] == tagCharCount) continue;
|
|
|
|
// alter the cursorMap by tagCharCount
|
|
currMathsInput.cursorMap[i][currMathsInput.cursorMap[i].length-1] -= tagCharCount;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
// update currMathsInput.text to be the same as currMathsInput.richText without any markuptags
|
|
currMathsInput.text = clone(currMathsInput.richText);
|
|
for (var p = 0; p < currMathsInput.text.length; p++) {
|
|
currMathsInput.text[p] = removeTags(currMathsInput.text[p]);
|
|
}
|
|
}
|
|
function combineSpacesCursor(array) {
|
|
//console.log(array.length);
|
|
if (array.length > 1) {
|
|
for (var gg = array.length - 1; gg >= 0; gg--) {
|
|
//console.log(gg, array[gg], typeof array[gg]);
|
|
if (typeof array[gg] == 'object') {
|
|
arrayString += '[' + gg + ']';
|
|
combineSpacesCursor(array[gg]);
|
|
} else {
|
|
if (gg < array.length - 1 && typeof array[gg] == 'string' && typeof array[gg+1] == 'string') {
|
|
eval('currMathsInput.richText' + arrayString + '[' + gg + '] += currMathsInput.richText' + arrayString + '[' + (gg+1) + ']');
|
|
eval('currMathsInput.richText' + arrayString + '.splice(gg+1, 1);');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
arrayString = arrayString.slice(0, arrayString.lastIndexOf('[') - arrayString.length);
|
|
return array;
|
|
}
|
|
function combineSpacesTextArray(array) {
|
|
if (array.length > 1) {
|
|
for (var i = array.length - 1; i >= 0; i--) {
|
|
if (typeof array[i] == 'object') {
|
|
if (i < array.length - 1 && typeof array[i] == 'string' && typeof array[i+1] == 'string') {
|
|
array[i] = array[i] + array[i+1];
|
|
array.splice(i+1,1);
|
|
}
|
|
} else {
|
|
combineSpacesTextArray(array[i]);
|
|
}
|
|
}
|
|
}
|
|
return array;
|
|
}
|
|
|
|
function mathsInputCursorCoords() { // updates cursor coordinates
|
|
drawMathsInputText(currMathsInput);
|
|
var char;
|
|
var cursorPos = currMathsInput.cursorMap[currMathsInput.cursorPos];
|
|
|
|
if (typeof cursorPos == 'undefined') return;
|
|
|
|
char = currMathsInput.textLoc;
|
|
for (var aa = 0 ; aa < cursorPos.length; aa++) {
|
|
char = char[cursorPos[aa]];
|
|
}
|
|
|
|
mathsInputCursor.x = char.left;
|
|
mathsInputCursor.top = char.top;
|
|
mathsInputCursor.bottom = char.top + char.height;
|
|
|
|
//logText(true);
|
|
|
|
//console.log('mathsInputCursor:',mathsInputCursor);
|
|
|
|
inputCursorState = false;
|
|
clearCorrectingInterval(mathsInputCursorBlinkInterval);
|
|
drawMathsInputText(currMathsInput);
|
|
mathsInputCursorBlink();
|
|
mathsInputCursorBlinkInterval = setCorrectingInterval(function(){mathsInputCursorBlink()}, 600);
|
|
blinking = true;
|
|
currMathsInput.stringJS = createJsString();
|
|
if (typeof textMenu !== 'undefined' && typeof textMenu !== 'undefined' && typeof textMenu.update == 'function') textMenu.update();
|
|
}
|
|
var showCursorPos = false;
|
|
function adjustForBreakPointsAllMap(pos) {
|
|
//console.log('pos:',pos);
|
|
if (typeof currMathsInput.breakPoints == 'object') {
|
|
//console.log('pos:',pos);
|
|
var map = currMathsInput.allMap[pos];
|
|
for (var i = 0; i < currMathsInput.breakPoints.length - 1; i++) {
|
|
var iBreak = currMathsInput.allMap[currMathsInput.breakPoints[i]];
|
|
if (iBreak[0] == map[0] && iBreak[1] < map[1]) {
|
|
pos--;
|
|
}
|
|
}
|
|
//console.log('pos:',pos);
|
|
}
|
|
return pos;
|
|
}
|
|
function adjustForBreakPoints(pos,map,breakPoints) {
|
|
if (typeof pos == 'undefined') pos = currMathsInput.cursorPos;
|
|
if (typeof map == 'undefined') map = currMathsInput.cursorMap[currMathsInput.cursorPos];
|
|
if (typeof breakPoints == 'undefined') breakPoints = currMathsInput.breakPoints;
|
|
|
|
if (typeof breakPoints == 'object') {
|
|
for (var i = 0; i < breakPoints.length - 1; i++) {
|
|
var iBreak = currMathsInput.allMap[breakPoints[i]];
|
|
//if (i > 0 && iBreak[1] - currMathsInput.allMap[breakPoints[i-1]][1] <= 7) continue;
|
|
//console.log(iBreak,iBreak[0] == map[0] && iBreak[1] < map[1]);
|
|
if (iBreak[0] == map[0] && iBreak[1] < map[1]) {
|
|
pos--;
|
|
}
|
|
}
|
|
}
|
|
|
|
return pos;
|
|
}
|
|
function mathsInputCursorBlink() {
|
|
if (inputCursorState == true) {inputCursorState = false} else {inputCursorState = true};
|
|
|
|
currMathsInput.cursorctx.clearRect(0,0,1200,700);
|
|
currMathsInput.cursorCanvas.style.zIndex = currMathsInput.canvas.style.zIndex + 1;
|
|
|
|
if (showCursorPos == true) {
|
|
for (var i = 0; i < currMathsInput.cursorMap.length; i++) {
|
|
var cPos = currMathsInput.textLoc;
|
|
|
|
for (var j = 0; j < currMathsInput.cursorMap[i].length; j++) {
|
|
cPos = cPos[currMathsInput.cursorMap[i][j]];
|
|
}
|
|
|
|
// adjust cPos to account for difference between canvas and cursor canvas positions
|
|
cPos.left += (currMathsInput.data[100] - currMathsInput.cursorData[100]);
|
|
cPos.top += (currMathsInput.data[101] - currMathsInput.cursorData[101]);
|
|
|
|
//console.log(cPos);
|
|
|
|
currMathsInput.cursorctx.save();
|
|
currMathsInput.cursorctx.strokeStyle = '#F00';
|
|
currMathsInput.cursorctx.lineWidth = 2;
|
|
currMathsInput.cursorctx.beginPath();
|
|
currMathsInput.cursorctx.moveTo(cPos.left, cPos.top);
|
|
currMathsInput.cursorctx.lineTo(cPos.left, cPos.top + cPos.height);
|
|
currMathsInput.cursorctx.closePath();
|
|
currMathsInput.cursorctx.stroke();
|
|
currMathsInput.cursorctx.restore();
|
|
}
|
|
} else if (inputCursorState == true && currMathsInput.selected == false) {
|
|
var hAdjust = currMathsInput.data[100] - currMathsInput.cursorData[100];
|
|
var vAdjust = currMathsInput.data[101] - currMathsInput.cursorData[101];
|
|
//console.log('blink',inputCursorState,currMathsInput.selected,mathsInputCursor,currMathsInput.cursorPos,hAdjust,vAdjust);
|
|
currMathsInput.cursorctx.save();
|
|
currMathsInput.cursorctx.strokeStyle = currMathsInput.textColor;
|
|
currMathsInput.cursorctx.lineWidth = 2;
|
|
currMathsInput.cursorctx.beginPath();
|
|
currMathsInput.cursorctx.moveTo(hAdjust + mathsInputCursor.x, vAdjust + mathsInputCursor.top);
|
|
currMathsInput.cursorctx.lineTo(hAdjust + mathsInputCursor.x, vAdjust + mathsInputCursor.bottom);
|
|
currMathsInput.cursorctx.closePath();
|
|
currMathsInput.cursorctx.stroke();
|
|
currMathsInput.cursorctx.restore();
|
|
} else {
|
|
//console.log('blink',inputCursorState,currMathsInput.selected,mathsInputCursor,currMathsInput.cursorPos);
|
|
}
|
|
}
|
|
|
|
//var shiftOn = false;
|
|
//window.addEventListener('keyup', shiftKeyUp, false);
|
|
/*function shiftKeyUp(e) {
|
|
e.preventDefault();
|
|
if (e.keyCode == 16) {
|
|
shiftOn = false;
|
|
}
|
|
}*/
|
|
function hardKeyMathsInput(e) { // if a key is pressed via the hardware keyboard
|
|
e.preventDefault();
|
|
if (inputState == true) {
|
|
var charCode = e.keyCode; // determine which key has been pressed
|
|
var keysToIgnore = [16,17,18,27,33,34,35,36,46,112,113,114,115,116,117,118,119,120,121,122,123,144,223];
|
|
if (e.getModifierState('Control')) {
|
|
if (charCode == 88) { //CTRL-x
|
|
mathsInputCut();
|
|
} else if (charCode == 67) { //CTRL-c
|
|
mathsInputCopy();
|
|
} else if (charCode == 86) { //CTRL-v
|
|
mathsInputPaste();
|
|
}
|
|
return;
|
|
}
|
|
if (e.getModifierState('Alt')) return;
|
|
switch (charCode) {
|
|
case 37 : // left arrow
|
|
currMathsInput.preText = '';
|
|
currMathsInput.postText = '';
|
|
if (e.getModifierState('Shift') == true && currMathsInput.cursorPos > 0) {
|
|
if (currMathsInput.selected == true) {
|
|
currMathsInput.selectPos[1] = [currMathsInput.cursorPos-1];
|
|
setSelectPositions();
|
|
drawMathsInputText(currMathsInput);
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos--;
|
|
} else {
|
|
currMathsInput.selected = true;
|
|
currMathsInput.selectPos = [currMathsInput.cursorPos,currMathsInput.cursorPos-1];
|
|
setSelectPositions();
|
|
drawMathsInputText(currMathsInput);
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos--;
|
|
}
|
|
} else if (currMathsInput.selected == true) {
|
|
removeSelectTags();
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos = Math.min(currMathsInput.selectPos[0],currMathsInput.selectPos[1]);
|
|
currMathsInput.selectPos = [];
|
|
mathsInputCursorCoords();
|
|
currMathsInput.selected = false;
|
|
removeSelectTags();
|
|
} else if (currMathsInput.cursorPos > 0) {
|
|
currMathsInput.cursorPos--;
|
|
mathsInputCursorCoords();
|
|
} else {
|
|
mathsInputTabPrev();
|
|
}
|
|
break;
|
|
case 38 : // up arrow
|
|
currMathsInput.preText = '';
|
|
currMathsInput.postText = '';
|
|
if (e.getModifierState('Shift') == true) {
|
|
if (currMathsInput.selected == false) {
|
|
currMathsInput.selectPos[0] = currMathsInput.cursorPos;
|
|
}
|
|
} else if (currMathsInput.selected == true) {
|
|
removeSelectTags();
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos = Math.min(currMathsInput.selectPos[0],currMathsInput.selectPos[1]);
|
|
currMathsInput.selectPos = [];
|
|
mathsInputCursorCoords();
|
|
currMathsInput.selected = false;
|
|
removeSelectTags();
|
|
}
|
|
var cursorPos = currMathsInput.cursorMap[currMathsInput.cursorPos];
|
|
// get the parent of the current string
|
|
var parent = currMathsInput.richText;
|
|
for (var i = 0; i < cursorPos.length - 3; i++) {parent = parent[cursorPos[i]]};
|
|
if (parent[0] == 'frac' && cursorPos[cursorPos.length - 3] == 2) {
|
|
currMathsInput.cursorPos -= cursorPos[cursorPos.length - 1];
|
|
currMathsInput.cursorPos--;
|
|
mathsInputCursorCoords();
|
|
} else {
|
|
// check if there is a row above
|
|
var lowerBreakPoints = [];
|
|
for (var i = 0; i < currMathsInput.breakPoints.length - 1; i++) {
|
|
if (currMathsInput.allMap[currMathsInput.breakPoints[i]][0] < currMathsInput.cursorMap[currMathsInput.cursorPos][0] || (currMathsInput.allMap[currMathsInput.breakPoints[i]][0] == currMathsInput.cursorMap[currMathsInput.cursorPos][0] && currMathsInput.allMap[currMathsInput.breakPoints[i]][1] < currMathsInput.cursorMap[currMathsInput.cursorPos][1])) {
|
|
lowerBreakPoints.unshift(currMathsInput.allMap[currMathsInput.breakPoints[i]]);
|
|
}
|
|
}
|
|
if (lowerBreakPoints.length == 0) {
|
|
// cursor is on top line
|
|
if (shiftOn == true) {
|
|
if (currMathsInput.selected == true) {
|
|
currMathsInput.selectPos[1] = 0;
|
|
} else {
|
|
currMathsInput.selectPos = [currMathsInput.cursorPos,0];
|
|
currMathsInput.selected = true;
|
|
}
|
|
setSelectPositions();
|
|
drawMathsInputText(currMathsInput);
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos = 0;
|
|
}
|
|
} else {
|
|
// get top point of current cursor position
|
|
var textLoc = currMathsInput.textLoc;
|
|
for (var i = 0; i < currMathsInput.cursorMap[currMathsInput.cursorPos].length; i++) {
|
|
textLoc = textLoc[currMathsInput.cursorMap[currMathsInput.cursorPos][i]];
|
|
}
|
|
var pos = [textLoc.left,textLoc.top];
|
|
// search through textLocs
|
|
var closestPos;
|
|
var closestDist;
|
|
for (var i = 0; i < currMathsInput.cursorMap.length; i++) {
|
|
// position must be less than lowerBreakPoints[0]
|
|
if (currMathsInput.cursorMap[i][0] < lowerBreakPoints[0][0] || (currMathsInput.cursorMap[i][0] == lowerBreakPoints[0][0] && currMathsInput.cursorMap[i][1] < lowerBreakPoints[0][1])) {
|
|
// if it is above the current line
|
|
|
|
// position must not be less than lowerBreakPoints[1]
|
|
if (lowerBreakPoints.length > 1) {
|
|
if (currMathsInput.cursorMap[i][0] < lowerBreakPoints[1][0] || (currMathsInput.cursorMap[i][0] == lowerBreakPoints[1][0] && currMathsInput.cursorMap[i][1] < lowerBreakPoints[1][1])) continue;
|
|
}
|
|
|
|
var loc = currMathsInput.textLoc;
|
|
for (var j = 0; j < currMathsInput.cursorMap[i].length; j++) {
|
|
loc = loc[currMathsInput.cursorMap[i][j]];
|
|
}
|
|
if (typeof closestPos == 'undefined') {
|
|
closestPos = i;
|
|
closestDist = distancePointToLineSegment(pos,[loc.left,loc.top],[loc.left,loc.top+loc.height]);
|
|
} else {
|
|
var newDist = distancePointToLineSegment(pos,[loc.left,loc.top],[loc.left,loc.top+loc.height]);
|
|
if (newDist < closestDist) {
|
|
closestPos = i;
|
|
closestDist = newDist;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (shiftOn == true) {
|
|
if (currMathsInput.selected == true) {
|
|
currMathsInput.selectPos[1] = closestPos;
|
|
} else {
|
|
currMathsInput.selectPos = [currMathsInput.cursorPos,closestPos];
|
|
currMathsInput.selected = true;
|
|
}
|
|
setSelectPositions();
|
|
drawMathsInputText(currMathsInput);
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos = closestPos;
|
|
} else {
|
|
currMathsInput.cursorPos = closestPos;
|
|
mathsInputCursorCoords();
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case 39 : // right arrow
|
|
currMathsInput.preText = '';
|
|
currMathsInput.postText = '';
|
|
if (e.getModifierState('Shift') == true && currMathsInput.cursorPos > 0) {
|
|
if (currMathsInput.selected == true) {
|
|
currMathsInput.selectPos[1] = [currMathsInput.cursorPos+1];
|
|
setSelectPositions();
|
|
drawMathsInputText(currMathsInput);
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos++;
|
|
} else {
|
|
currMathsInput.selected = true;
|
|
currMathsInput.selectPos = [currMathsInput.cursorPos,currMathsInput.cursorPos+1];
|
|
setSelectPositions();
|
|
drawMathsInputText(currMathsInput);
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos++;
|
|
}
|
|
} else if (currMathsInput.selected == true) {
|
|
removeSelectTags();
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos = Math.max(currMathsInput.selectPos[0],currMathsInput.selectPos[1]);
|
|
currMathsInput.selectPos = [];
|
|
mathsInputCursorCoords();
|
|
currMathsInput.selected = false;
|
|
removeSelectTags();
|
|
} else if (currMathsInput.cursorPos < currMathsInput.cursorMap.length - 1) {
|
|
currMathsInput.cursorPos++;
|
|
mathsInputCursorCoords();
|
|
} else {
|
|
mathsInputTabNext();
|
|
}
|
|
break;
|
|
case 40 : // down arrow
|
|
currMathsInput.preText = '';
|
|
currMathsInput.postText = '';
|
|
if (e.getModifierState('Shift') == true) {
|
|
if (currMathsInput.selected == false) {
|
|
currMathsInput.selectPos[0] = currMathsInput.cursorPos;
|
|
}
|
|
} else if (currMathsInput.selected == true) {
|
|
removeSelectTags();
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos = Math.max(currMathsInput.selectPos[0],currMathsInput.selectPos[1]);
|
|
currMathsInput.selectPos = [];
|
|
mathsInputCursorCoords();
|
|
currMathsInput.selected = false;
|
|
removeSelectTags();
|
|
}
|
|
var cursorPos = currMathsInput.cursorMap[currMathsInput.cursorPos];
|
|
// get the parent of the current string
|
|
var parent = currMathsInput.richText;
|
|
for (var aa = 0; aa < cursorPos.length - 3; aa++) {parent = parent[cursorPos[aa]]};
|
|
if (parent[0] == 'frac' && cursorPos[cursorPos.length - 3] == 1) {
|
|
// move to the beginning of the denominator text
|
|
do {
|
|
currMathsInput.cursorPos++;
|
|
var cursorPos2 = currMathsInput.cursorMap[currMathsInput.cursorPos];
|
|
// get the parent of the cursorPos
|
|
var parent2 = currMathsInput.richText;
|
|
for (var aa = 0; aa < cursorPos2.length - 3; aa++) {parent2 = parent2[cursorPos2[aa]]};
|
|
} while ((parent2 !== parent) || (parent2 == parent && cursorPos2[cursorPos.length - 3] !== 2));
|
|
// move to the end of the denominator text
|
|
do {
|
|
currMathsInput.cursorPos++;
|
|
var cursorPos2 = currMathsInput.cursorMap[currMathsInput.cursorPos];
|
|
} while (cursorPos2.length >= cursorPos.length);
|
|
currMathsInput.cursorPos--;
|
|
mathsInputCursorCoords();
|
|
} else {
|
|
var higherBreakPoints = [];
|
|
for (var i = 0; i < currMathsInput.breakPoints.length - 1; i++) {
|
|
if (currMathsInput.allMap[currMathsInput.breakPoints[i]][0] > currMathsInput.cursorMap[currMathsInput.cursorPos][0] || (currMathsInput.allMap[currMathsInput.breakPoints[i]][0] == currMathsInput.cursorMap[currMathsInput.cursorPos][0] && currMathsInput.allMap[currMathsInput.breakPoints[i]][1] > currMathsInput.cursorMap[currMathsInput.cursorPos][1])) {
|
|
higherBreakPoints.push(currMathsInput.allMap[currMathsInput.breakPoints[i]]);
|
|
}
|
|
}
|
|
if (higherBreakPoints.length == 0) {
|
|
// cursor is on bottom line
|
|
if (shiftOn == true) {
|
|
if (currMathsInput.selected == true) {
|
|
currMathsInput.selectPos[1] = currMathsInput.cursorMap.length - 1;
|
|
} else {
|
|
currMathsInput.selectPos = [currMathsInput.cursorPos,currMathsInput.cursorMap.length - 1];
|
|
currMathsInput.selected = true;
|
|
}
|
|
setSelectPositions();
|
|
drawMathsInputText(currMathsInput);
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos = currMathsInput.cursorMap.length - 1;
|
|
}
|
|
} else {
|
|
// get bottom point of current cursor position
|
|
var textLoc = currMathsInput.textLoc;
|
|
for (var i = 0; i < currMathsInput.cursorMap[currMathsInput.cursorPos].length; i++) {
|
|
textLoc = textLoc[currMathsInput.cursorMap[currMathsInput.cursorPos][i]];
|
|
}
|
|
var pos = [textLoc.left,textLoc.top+textLoc.height];
|
|
// search through textLocs
|
|
var closestPos;
|
|
var closestDist;
|
|
for (var i = 0; i < currMathsInput.cursorMap.length; i++) {
|
|
// position must be more than higherBreakPoints[0]
|
|
if (currMathsInput.cursorMap[i][0] > higherBreakPoints[0][0] || (currMathsInput.cursorMap[i][0] == higherBreakPoints[0][0] && currMathsInput.cursorMap[i][1] > higherBreakPoints[0][1])) {
|
|
// if it is above the current line
|
|
|
|
// position must not be less than higherBreakPoints[1]
|
|
if (higherBreakPoints.length > 1) {
|
|
if (currMathsInput.cursorMap[i][0] > higherBreakPoints[1][0] || (currMathsInput.cursorMap[i][0] == higherBreakPoints[1][0] && currMathsInput.cursorMap[i][1] > higherBreakPoints[1][1])) continue;
|
|
}
|
|
var loc = currMathsInput.textLoc;
|
|
for (var j = 0; j < currMathsInput.cursorMap[i].length; j++) {
|
|
loc = loc[currMathsInput.cursorMap[i][j]];
|
|
}
|
|
if (typeof closestPos == 'undefined') {
|
|
closestPos = i;
|
|
closestDist = distancePointToLineSegment(pos,[loc.left,loc.top],[loc.left,loc.top+loc.height]);
|
|
} else {
|
|
var newDist = distancePointToLineSegment(pos,[loc.left,loc.top],[loc.left,loc.top+loc.height]);
|
|
if (newDist < closestDist) {
|
|
closestPos = i;
|
|
closestDist = newDist;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (shiftOn == true) {
|
|
if (currMathsInput.selected == true) {
|
|
currMathsInput.selectPos[1] = closestPos;
|
|
} else {
|
|
currMathsInput.selectPos = [currMathsInput.cursorPos,closestPos];
|
|
currMathsInput.selected = true;
|
|
}
|
|
setSelectPositions();
|
|
drawMathsInputText(currMathsInput);
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos = closestPos;
|
|
} else {
|
|
currMathsInput.cursorPos = closestPos;
|
|
mathsInputCursorCoords();
|
|
}
|
|
}
|
|
|
|
}
|
|
break;
|
|
case 8 : // backspace key pressed
|
|
currMathsInput.preText = '';
|
|
currMathsInput.postText = '';
|
|
if (currMathsInput.selected == true) {
|
|
currMathsInput.cursorPos = Math.min(currMathsInput.selectPos[0],currMathsInput.selectPos[1]);
|
|
currMathsInput.selPos = [];
|
|
currMathsInput.selected = false;
|
|
deleteSelected();
|
|
removeSelectTags();
|
|
drawMathsInputText(currMathsInput);
|
|
mathsInputMapCursorPos();
|
|
mathsInputCursorCoords();
|
|
} else if (currMathsInput.cursorPos > 0) {
|
|
removeSelectTags();
|
|
// get the relevant string from currMathsInput.richText
|
|
// ie. currMathsInput.richText[cursorPos[0]][cursorPos[1]]...[cursorPos[n]]
|
|
var cursorPos = currMathsInput.cursorMap[currMathsInput.cursorPos];
|
|
var pos = cursorPos[cursorPos.length - 1];
|
|
pos = adjustForBreakPoints(pos);
|
|
|
|
var text = currMathsInput.richText;
|
|
for (var i = 0; i < cursorPos.length - 1; i++) {text = text[cursorPos[i]]};
|
|
|
|
var parent;
|
|
if (cursorPos.length > 1) {
|
|
parent = currMathsInput.richText;
|
|
for (var i = 0; i < cursorPos.length - 2; i++) {parent = parent[cursorPos[i]]};
|
|
}
|
|
var grandParent;
|
|
if (cursorPos.length > 2) {
|
|
grandParent = currMathsInput.richText;
|
|
for (var i = 0; i < cursorPos.length - 3; i++) {grandParent = grandParent[cursorPos[i]]};
|
|
}
|
|
|
|
if (text !== '') {
|
|
if (pos !== 0) {
|
|
//console.clear();
|
|
//console.log(1,text,pos,text.slice(pos-1));
|
|
if (text.slice(pos-6).indexOf('<<br>>') == 0) {
|
|
text = text.slice(0, pos-6) + text.slice(pos);
|
|
} else {
|
|
text = text.slice(0, pos-1) + text.slice(pos);
|
|
}
|
|
//console.log(2,text);
|
|
// replace the string
|
|
var evalString = 'currMathsInput.richText'
|
|
for (var aa = 0; aa < cursorPos.length - 1; aa++) {
|
|
// ugly string creation apprach in order to use eval()
|
|
evalString += '[' + cursorPos[aa] + ']';
|
|
}
|
|
eval(evalString + ' = text;');
|
|
}
|
|
} else {
|
|
if (parent.length == 1) { // ie. empty string is only sub-element
|
|
var elemsOneParam = ['sqrt', 'pow', 'power', 'subs', 'subscript', 'sin', 'cos', 'tan', 'sin-1', 'cos-1', 'tan-1', 'log', 'ln', 'abs', 'exp', 'sigma1', 'int1', 'vectorArrow', 'bar', 'hat', 'recurring'];
|
|
var elemsTwoParams = ['root', 'frac', 'logBase', 'colVector2d', 'lim'];
|
|
var elemsThreeParams = ['sigma2', 'int2', 'colVector3d', 'mixedNum'];
|
|
if (elemsOneParam.indexOf(grandParent[0]) > -1 || (elemsTwoParams.indexOf(grandParent[0]) > -1 && cursorPos[cursorPos.length - 3] == 1) || (elemsThreeParams.indexOf(grandParent[0]) > -1 && cursorPos[cursorPos.length - 3] == 1)) { // conditions to delete
|
|
// replace grandParent with "";
|
|
var evalString = 'currMathsInput.richText'
|
|
for (var i = 0; i < cursorPos.length - 3; i++) {
|
|
// ugly string creation apprach in order to use eval()
|
|
evalString += '[' + cursorPos[i] + ']';
|
|
}
|
|
eval(evalString + ' = "";');
|
|
}
|
|
}
|
|
}
|
|
//console.log(JSON.stringify(currMathsInput.richText));
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos--;
|
|
mathsInputCursorCoords();
|
|
}
|
|
break;
|
|
case 46 : // delete key
|
|
currMathsInput.preText = '';
|
|
currMathsInput.postText = '';
|
|
if (currMathsInput.selected == true) {
|
|
currMathsInput.cursorPos = Math.min(currMathsInput.selectPos[0],currMathsInput.selectPos[1]);
|
|
currMathsInput.selPos = [];
|
|
currMathsInput.selected = false;
|
|
deleteSelected();
|
|
removeSelectTags();
|
|
drawMathsInputText(currMathsInput);
|
|
mathsInputMapCursorPos();
|
|
mathsInputCursorCoords();
|
|
} else if (currMathsInput.cursorPos < currMathsInput.cursorMap.length - 1) {
|
|
// get the relevant string from currMathsInput.richText
|
|
// ie. currMathsInput.richText[cursorPos[0]][cursorPos[1]]...[cursorPos[n]]
|
|
var cursorPos = currMathsInput.cursorMap[currMathsInput.cursorPos];
|
|
var pos = cursorPos[cursorPos.length - 1];
|
|
pos = adjustForBreakPoints(pos);
|
|
|
|
var text = currMathsInput.richText;
|
|
for (var i = 0; i < cursorPos.length - 1; i++) {text = text[cursorPos[i]]};
|
|
|
|
if (cursorPos[cursorPos.length - 1] !== text.length) {
|
|
if (text.slice(pos).indexOf('<<br>>') == 0) {
|
|
text = text.slice(0,pos) + text.slice(pos+6);
|
|
} else if (text.slice(pos).indexOf('<<') == 0) {
|
|
//skip forward to end of tags
|
|
var text2 = text.slice(pos);
|
|
var endFound = false;
|
|
var charCount = 0;
|
|
do {
|
|
var c = text2.indexOf('>>') + 2;
|
|
charCount += c;
|
|
var text2 = text2.slice(c);
|
|
if (text2.indexOf('<<') !== 0) {
|
|
endFound = true;
|
|
}
|
|
} while (endFound == false);
|
|
pos += charCount;
|
|
text = text.slice(0,pos) + text.slice(pos+1);
|
|
} else {
|
|
text = text.slice(0,pos) + text.slice(pos+1);
|
|
}
|
|
// replace the string
|
|
var evalString = 'currMathsInput.richText'
|
|
for (var i = 0; i < cursorPos.length - 1; i++) {
|
|
// ugly string creation apprach in order to use eval()
|
|
evalString += '[' + cursorPos[i] + ']';
|
|
}
|
|
eval(evalString + ' = text;');
|
|
mathsInputMapCursorPos();
|
|
mathsInputCursorCoords();
|
|
}
|
|
}
|
|
break;
|
|
case 9 : // tab key pressed
|
|
if (typeof draw !== 'undefined' && draw.drawMode == 'textEdit') {
|
|
if (e.getModifierState('Control')) {
|
|
mathsInputTab(10);
|
|
} else if (e.getModifierState('Shift')) {
|
|
mathsInputTab(5);
|
|
} else {
|
|
mathsInputTab();
|
|
}
|
|
} else {
|
|
mathsInputTabNext();
|
|
}
|
|
break;
|
|
case 13 : // enter key pressed
|
|
if (currMathsInput.maxLines > 1 || (typeof draw !== 'undefined' && draw.drawMode == 'textEdit')) {
|
|
if (currMathsInput.selected == true) {
|
|
currMathsInput.cursorPos = Math.min(currMathsInput.selectPos[0],currMathsInput.selectPos[1]);
|
|
currMathsInput.selPos = [];
|
|
currMathsInput.selected = false;
|
|
deleteSelected();
|
|
removeSelectTags();
|
|
drawMathsInputText(currMathsInput);
|
|
mathsInputMapCursorPos();
|
|
mathsInputCursorCoords();
|
|
}
|
|
mathsInputNewLine();
|
|
} else {
|
|
endMathsInput(e);
|
|
}
|
|
break;
|
|
case 27 : // escape key pressed
|
|
endMathsInput(e);
|
|
break;
|
|
/*case 16 : //shift key pressed
|
|
shiftOn = true;
|
|
window.addEventListener('keyup', shiftKeyUp, false);
|
|
break;*/
|
|
default :
|
|
|
|
// need to protect against << or >> being entered
|
|
|
|
if (currMathsInput.text[0].length >= currMathsInput.maxChars) {break};
|
|
if (e.getModifierState('Shift') == true && charCode == 54/* && currMathsInput.cursorMap[currMathsInput.cursorPos].length == 2*/) { // if hat symbol is used and current text element is a text string
|
|
mathsInputPow();
|
|
break;
|
|
}
|
|
if (keysToIgnore.indexOf(charCode) == -1) {
|
|
|
|
if (currMathsInput.selected == true) {
|
|
currMathsInput.cursorPos = Math.min(currMathsInput.selectPos[0],currMathsInput.selectPos[1]);
|
|
currMathsInput.selPos = [];
|
|
currMathsInput.selected = false;
|
|
deleteSelected();
|
|
removeSelectTags();
|
|
drawMathsInputText(currMathsInput);
|
|
mathsInputMapCursorPos();
|
|
mathsInputCursorCoords();
|
|
}
|
|
|
|
var caps = false;
|
|
if (e.getModifierState('Shift') || e.getModifierState('CapsLock')) caps = true
|
|
|
|
for (var ii = 0; ii < charMap.length; ii++) {
|
|
if (charCode == charMap[ii][0]) {
|
|
if (caps) {
|
|
charCode = charMap[ii][2];
|
|
} else {
|
|
charCode = charMap[ii][1];
|
|
}
|
|
}
|
|
}
|
|
// if it is a letter key and shift is not pressed, use lower case instead of upper case
|
|
if (!caps && charCode >= 65 && charCode <= 90) charCode += 32;
|
|
var keyValue = String.fromCharCode(charCode);
|
|
|
|
// get the relevant string from currMathsInput.richText
|
|
// ie. currMathsInput.richText[cursorPos[0]][cursorPos[1]]...[cursorPos[n]]
|
|
//console.log(currMathsInput.cursorMap,currMathsInput.cursorPos,currMathsInput.cursorMap[currMathsInput.cursorPos]);
|
|
var cursorPos = currMathsInput.cursorMap[currMathsInput.cursorPos];
|
|
|
|
/*
|
|
console.log('currMathsInput.cursorMap:',JSON.stringify(currMathsInput.cursorMap,null,4),currMathsInput.cursorMap.length-1);
|
|
console.log('currMathsInput.cursorPos:',JSON.stringify(currMathsInput.cursorPos,null,4));
|
|
console.log('currMathsInput.cursorMap[currMathsInput.cursorPos]:',JSON.stringify(currMathsInput.cursorMap[currMathsInput.cursorPos],null,4));
|
|
console.log('currMathsInput.richText[0]:',JSON.stringify(currMathsInput.richText[0],null,4),currMathsInput.richText[0].length-1);
|
|
console.log('cursorPos:',JSON.stringify(cursorPos,null,4));
|
|
*/
|
|
|
|
var text = currMathsInput.richText;
|
|
for (var i = 0; i < cursorPos.length - 1; i++) {
|
|
text = text[cursorPos[i]];
|
|
}
|
|
|
|
var slicePos = cursorPos[cursorPos.length - 1];
|
|
slicePos = adjustForBreakPoints(slicePos);
|
|
|
|
/*var prev = 0;
|
|
var breakPoints = currMathsInput.breakPoints;
|
|
for (var b = 0; b < breakPoints.length; b++) {
|
|
prev = breakPoints[b];
|
|
}*/
|
|
|
|
//console.log(text,slicePos);
|
|
|
|
slicePos = mathsInputAvoidTagSplit(text,slicePos);
|
|
/* this section replaced by the function above
|
|
// check that a tag is not being split - if so adjust slicePos
|
|
var leftText = text.slice(0,slicePos);
|
|
var rightText = text.slice(slicePos);
|
|
var tagLeft = false;
|
|
var tagLeftCount = 0;
|
|
for (var i = 0; i < leftText.length; i++) {
|
|
tagLeftCount++;
|
|
//console.log('left '+i+':',leftText.slice(leftText.length - i));
|
|
if (leftText.slice(leftText.length - i).indexOf('>>') == 0) break;
|
|
if (leftText.slice(leftText.length - i).indexOf('<<') == 0) {
|
|
tagLeft = true;
|
|
break;
|
|
}
|
|
}
|
|
var tagRight = false;
|
|
var tagRightCount = 0;
|
|
for (var j = 0; j < rightText.length; j++) {
|
|
tagRightCount++;
|
|
//console.log('right '+j+':',rightText.slice(j));
|
|
if (rightText.slice(j).indexOf('<<') == 0) break;
|
|
if (rightText.slice(j).indexOf('>>') == 0) {
|
|
tagRight = true;
|
|
break;
|
|
}
|
|
}
|
|
//console.log(tagLeft,tagRight,tagLeftCount,tagRightCount);
|
|
if (tagLeft == true && tagRight == true) {
|
|
if (tagLeftCount <= tagRightCount) {
|
|
slicePos -= tagLeftCount;
|
|
} else {
|
|
slicePos += tagRightCount;
|
|
}
|
|
}
|
|
// test if '<',slicePos,'<' or '>',slicePos,'>'
|
|
if (leftText.slice(-1) == '<' && rightText.slice(0,1) == '<' && rightText.slice(0,2) !== '<<') slicePos--;
|
|
if (leftText.slice(-1) == '>' && leftText.slice(-2) !== '>>' && rightText.slice(0,1) == '>') slicePos++;*/
|
|
|
|
if (un(currMathsInput.preText) || currMathsInput.preText == null) {
|
|
var pre = "";
|
|
} else {
|
|
var pre = currMathsInput.preText;
|
|
}
|
|
if (un(currMathsInput.postText) || currMathsInput.postText == null) {
|
|
var post = "";
|
|
} else {
|
|
var post = currMathsInput.postText;
|
|
}
|
|
|
|
text = text.slice(0, slicePos) + pre + keyValue + post + text.slice(slicePos);
|
|
|
|
// replace the string
|
|
var evalString = 'currMathsInput.richText'
|
|
for (var i = 0; i < cursorPos.length - 1; i++) {
|
|
// ugly string creation apprach in order to use eval()
|
|
evalString += '[' + cursorPos[i] + ']';
|
|
}
|
|
eval(evalString + ' = text;');
|
|
|
|
//logText();
|
|
mathsInputMapCursorPos();
|
|
|
|
// set the last number of cursorMap[cursorPos+1] to be one more than cursorMap[cursorPos]
|
|
//currMathsInput.cursorMap[currMathsInput.cursorPos + 1][currMathsInput.cursorMap[currMathsInput.cursorPos + 1].length - 1] = currMathsInput.cursorMap[currMathsInput.cursorPos][currMathsInput.cursorMap[currMathsInput.cursorPos].length - 1] + 1;
|
|
|
|
currMathsInput.cursorPos += 1;
|
|
mathsInputCursorCoords();
|
|
currMathsInput.preText = '';
|
|
currMathsInput.postText = '';
|
|
//logText();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function softKeyMathsInput(e) {
|
|
//console.log(inputState);
|
|
if (inputState == true) {
|
|
/*
|
|
if (mathsInputDoubleInput == true) {
|
|
return;
|
|
} else {
|
|
mathsInputDoubleInput = true;
|
|
setTimeout(function() {
|
|
mathsInputDoubleInput = false;
|
|
}, 250);
|
|
}
|
|
*/
|
|
var keyNum;
|
|
var keyValue;
|
|
if (keyboard[pageIndex]) {
|
|
keyNum = key1[pageIndex].indexOf(e.target);
|
|
keyValue = key1Data[pageIndex][keyNum][6];
|
|
}
|
|
//console.log(keyValue);
|
|
if (keyValue == 'delete') { // if it's the delete button
|
|
currMathsInput.preText = '';
|
|
currMathsInput.postText = '';
|
|
if (currMathsInput.selected == true) {
|
|
currMathsInput.cursorPos = Math.min(currMathsInput.selectPos[0],currMathsInput.selectPos[1]);
|
|
currMathsInput.selPos = [];
|
|
currMathsInput.selected = false;
|
|
deleteSelected();
|
|
removeSelectTags();
|
|
drawMathsInputText(currMathsInput);
|
|
mathsInputMapCursorPos();
|
|
mathsInputCursorCoords();
|
|
} else if (currMathsInput.cursorPos > 0) {
|
|
// get the relevant string from currMathsInput.richText
|
|
// ie. currMathsInput.richText[cursorPos[0]][cursorPos[1]]...[cursorPos[n]]
|
|
var cursorPos = currMathsInput.cursorMap[currMathsInput.cursorPos];
|
|
//console.log(cursorPos);
|
|
var pos = cursorPos[cursorPos.length - 1];
|
|
//console.log(pos);
|
|
pos = adjustForBreakPoints(pos);
|
|
//console.log(pos);
|
|
|
|
var text = currMathsInput.richText;
|
|
for (var i = 0; i < cursorPos.length - 1; i++) {text = text[cursorPos[i]]};
|
|
|
|
var parent;
|
|
if (cursorPos.length > 1) {
|
|
parent = currMathsInput.richText;
|
|
for (var i = 0; i < cursorPos.length - 2; i++) {parent = parent[cursorPos[i]]};
|
|
}
|
|
var grandParent;
|
|
if (cursorPos.length > 2) {
|
|
grandParent = currMathsInput.richText;
|
|
for (var i = 0; i < cursorPos.length - 3; i++) {grandParent = grandParent[cursorPos[i]]};
|
|
}
|
|
|
|
if (text !== '') {
|
|
if (pos !== 0) {
|
|
//console.log(1,text,text.length,pos,text.slice(0, pos-1) + text.slice(pos));
|
|
if (text.slice(pos-6).indexOf('<<br>>') == 0) {
|
|
text = text.slice(0, pos-6) + text.slice(pos);
|
|
} else {
|
|
text = text.slice(0, pos-1) + text.slice(pos);
|
|
}
|
|
//console.log(2,text);
|
|
// replace the string
|
|
var evalString = 'currMathsInput.richText'
|
|
for (var aa = 0; aa < cursorPos.length - 1; aa++) {
|
|
// ugly string creation apprach in order to use eval()
|
|
evalString += '[' + cursorPos[aa] + ']';
|
|
}
|
|
eval(evalString + ' = text;');
|
|
}
|
|
} else {
|
|
if (parent.length == 1) { // ie. empty string is only sub-element
|
|
var elemsOneParam = ['sqrt', 'pow', 'power', 'subs', 'subscript', 'sin', 'cos', 'tan', 'sin-1', 'cos-1', 'tan-1', 'log', 'ln', 'abs', 'exp', 'sigma1', 'int1', 'vectorArrow', 'bar', 'hat', 'recurring'];
|
|
var elemsTwoParams = ['root', 'frac', 'logBase', 'colVector2d', 'lim'];
|
|
var elemsThreeParams = ['sigma2', 'int2', 'colVector3d', 'mixedNum'];
|
|
if (elemsOneParam.indexOf(grandParent[0]) > -1 || (elemsTwoParams.indexOf(grandParent[0]) > -1 && cursorPos[cursorPos.length - 3] == 1) || (elemsThreeParams.indexOf(grandParent[0]) > -1 && cursorPos[cursorPos.length - 3] == 1)) { // conditions to delete elements
|
|
// replace grandParent with "";
|
|
var evalString = 'currMathsInput.richText'
|
|
for (var i = 0; i < cursorPos.length - 3; i++) {
|
|
// ugly string creation apprach in order to use eval()
|
|
evalString += '[' + cursorPos[i] + ']';
|
|
}
|
|
eval(evalString + ' = "";');
|
|
}
|
|
}
|
|
}
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos--;
|
|
mathsInputCursorCoords();
|
|
}
|
|
} else {
|
|
// type text char
|
|
if (currMathsInput.text[0].length >= currMathsInput.maxChars) {return};
|
|
|
|
if (currMathsInput.selected == true) {
|
|
currMathsInput.cursorPos = Math.min(currMathsInput.selectPos[0],currMathsInput.selectPos[1]);
|
|
currMathsInput.selPos = [];
|
|
currMathsInput.selected = false;
|
|
deleteSelected();
|
|
removeSelectTags();
|
|
drawMathsInputText(currMathsInput);
|
|
mathsInputMapCursorPos();
|
|
mathsInputCursorCoords();
|
|
}
|
|
|
|
// get the relevant string from currMathsInput.richText
|
|
// ie. currMathsInput.richText[cursorPos[0]][cursorPos[1]]...[cursorPos[n]]
|
|
var cursorPos = currMathsInput.cursorMap[currMathsInput.cursorPos];
|
|
|
|
var text = currMathsInput.richText;
|
|
for (var aa = 0; aa < cursorPos.length - 1; aa++) {
|
|
text = text[cursorPos[aa]];
|
|
}
|
|
|
|
/*
|
|
// test if sin, cos, tan, ln or log have been written:
|
|
if (keyValue == 'n' && text.length > 1 && text.slice(cursorPos[cursorPos.length - 1] - 2, cursorPos[cursorPos.length - 1]) == 'si') {
|
|
// get cursorPos
|
|
var cursorPos = currMathsInput.cursorMap[currMathsInput.cursorPos];
|
|
// get parent
|
|
var parent = currMathsInput.richText;
|
|
for (var aa = 0; aa < cursorPos.length - 1; aa++) {parent = parent[cursorPos[aa]]};
|
|
// get position of cursor in parent string
|
|
var pos = cursorPos[cursorPos.length - 1];
|
|
var parentPos = cursorPos[cursorPos.length - 2];
|
|
|
|
var evalString = 'currMathsInput.richText'
|
|
for (var aa = 0; aa < cursorPos.length - 2; aa++) {
|
|
// ugly string creation apprach in order to use eval()
|
|
evalString += '[' + cursorPos[aa] + ']';
|
|
}
|
|
eval(evalString + ".splice(parentPos, 1, parent.slice(0, pos - 2), ['sin', ['']], parent.slice(pos));");
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos--;
|
|
mathsInputCursorCoords();
|
|
return;
|
|
}
|
|
if (keyValue == 's' && text.length > 1 && text.slice(cursorPos[cursorPos.length - 1] - 2, cursorPos[cursorPos.length - 1]) == 'co') {
|
|
// get cursorPos
|
|
var cursorPos = currMathsInput.cursorMap[currMathsInput.cursorPos];
|
|
// get parent
|
|
var parent = currMathsInput.richText;
|
|
for (var aa = 0; aa < cursorPos.length - 1; aa++) {parent = parent[cursorPos[aa]]};
|
|
// get position of cursor in parent string
|
|
var pos = cursorPos[cursorPos.length - 1];
|
|
var parentPos = cursorPos[cursorPos.length - 2];
|
|
|
|
var evalString = 'currMathsInput.richText'
|
|
for (var aa = 0; aa < cursorPos.length - 2; aa++) {
|
|
// ugly string creation apprach in order to use eval()
|
|
evalString += '[' + cursorPos[aa] + ']';
|
|
}
|
|
eval(evalString + ".splice(parentPos, 1, parent.slice(0, pos - 2), ['cos', ['']], parent.slice(pos));");
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos--;
|
|
mathsInputCursorCoords();
|
|
return;
|
|
}
|
|
if (keyValue == 'n' && text.length > 1 && text.slice(cursorPos[cursorPos.length - 1] - 2, cursorPos[cursorPos.length - 1]) == 'ta') {
|
|
console.log('tan');
|
|
// get cursorPos
|
|
var cursorPos = currMathsInput.cursorMap[currMathsInput.cursorPos];
|
|
// get parent
|
|
var parent = currMathsInput.richText;
|
|
for (var aa = 0; aa < cursorPos.length - 1; aa++) {parent = parent[cursorPos[aa]]};
|
|
// get position of cursor in parent string
|
|
var pos = cursorPos[cursorPos.length - 1];
|
|
var parentPos = cursorPos[cursorPos.length - 2];
|
|
|
|
var evalString = 'currMathsInput.richText'
|
|
for (var aa = 0; aa < cursorPos.length - 2; aa++) {
|
|
// ugly string creation apprach in order to use eval()
|
|
evalString += '[' + cursorPos[aa] + ']';
|
|
}
|
|
eval(evalString + ".splice(parentPos, 1, parent.slice(0, pos - 2), ['tan', ['']], parent.slice(pos));");
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos--;
|
|
mathsInputCursorCoords();
|
|
return;
|
|
}
|
|
if (keyValue == 'n' && text.length > 0 && text.slice(cursorPos[cursorPos.length - 1] - 1, cursorPos[cursorPos.length - 1]) == 'l') {
|
|
console.log('ln');
|
|
// get cursorPos
|
|
var cursorPos = currMathsInput.cursorMap[currMathsInput.cursorPos];
|
|
// get parent
|
|
var parent = currMathsInput.richText;
|
|
for (var aa = 0; aa < cursorPos.length - 1; aa++) {parent = parent[cursorPos[aa]]};
|
|
// get position of cursor in parent string
|
|
var pos = cursorPos[cursorPos.length - 1];
|
|
var parentPos = cursorPos[cursorPos.length - 2];
|
|
|
|
var evalString = 'currMathsInput.richText'
|
|
for (var aa = 0; aa < cursorPos.length - 2; aa++) {
|
|
// ugly string creation apprach in order to use eval()
|
|
evalString += '[' + cursorPos[aa] + ']';
|
|
}
|
|
eval(evalString + ".splice(parentPos, 1, parent.slice(0, pos - 1), ['ln', ['']], parent.slice(pos));");
|
|
mathsInputMapCursorPos();
|
|
mathsInputCursorCoords();
|
|
return;
|
|
}
|
|
if (keyValue == 'g' && text.length > 1 && text.slice(cursorPos[cursorPos.length - 1] - 2, cursorPos[cursorPos.length - 1]) == 'lo') {
|
|
console.log('log');
|
|
// get cursorPos
|
|
var cursorPos = currMathsInput.cursorMap[currMathsInput.cursorPos];
|
|
// get parent
|
|
var parent = currMathsInput.richText;
|
|
for (var aa = 0; aa < cursorPos.length - 1; aa++) {parent = parent[cursorPos[aa]]};
|
|
// get position of cursor in parent string
|
|
var pos = cursorPos[cursorPos.length - 1];
|
|
var parentPos = cursorPos[cursorPos.length - 2];
|
|
|
|
var evalString = 'currMathsInput.richText'
|
|
for (var aa = 0; aa < cursorPos.length - 2; aa++) {
|
|
// ugly string creation apprach in order to use eval()
|
|
evalString += '[' + cursorPos[aa] + ']';
|
|
}
|
|
eval(evalString + ".splice(parentPos, 1, parent.slice(0, pos - 2), ['log', ['']], parent.slice(pos));");
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos--;
|
|
mathsInputCursorCoords();
|
|
return;
|
|
}
|
|
*/
|
|
|
|
var slicePos = cursorPos[cursorPos.length - 1];
|
|
slicePos = adjustForBreakPoints(slicePos);
|
|
//console.log(slicePos);
|
|
|
|
slicePos = mathsInputAvoidTagSplit(text,slicePos);
|
|
/* the section below is replaced by the function above
|
|
// check that a tag is not being split - if so adjust slicePos
|
|
var leftText = text.slice(0,slicePos);
|
|
var rightText = text.slice(slicePos);
|
|
var tagLeft = false;
|
|
var tagLeftCount = 0;
|
|
for (var i = 0; i < leftText.length; i++) {
|
|
tagLeftCount++;
|
|
//console.log('left '+i+':',leftText.slice(leftText.length - i));
|
|
if (leftText.slice(leftText.length - i).indexOf('>>') == 0) break;
|
|
if (leftText.slice(leftText.length - i).indexOf('<<') == 0) {
|
|
tagLeft = true;
|
|
break;
|
|
}
|
|
}
|
|
var tagRight = false;
|
|
var tagRightCount = 0;
|
|
for (var j = 0; j < rightText.length; j++) {
|
|
tagRightCount++;
|
|
//console.log('right '+j+':',rightText.slice(j));
|
|
if (rightText.slice(j).indexOf('<<') == 0) break;
|
|
if (rightText.slice(j).indexOf('>>') == 0) {
|
|
tagRight = true;
|
|
break;
|
|
}
|
|
}
|
|
//console.log(tagLeft,tagRight,tagLeftCount,tagRightCount);
|
|
if (tagLeft == true && tagRight == true) {
|
|
if (tagLeftCount <= tagRightCount) {
|
|
slicePos -= tagLeftCount;
|
|
} else {
|
|
slicePos += tagRightCount;
|
|
}
|
|
}
|
|
// test if '<',slicePos,'<' or '>',slicePos,'>'
|
|
if (leftText.slice(-1) == '<' && rightText.slice(0,1) == '<' && rightText.slice(0,2) !== '<<') slicePos--;
|
|
if (leftText.slice(-1) == '>' && leftText.slice(-2) !== '>>' && rightText.slice(0,1) == '>') slicePos++;*/
|
|
|
|
|
|
if (un(currMathsInput.preText) || currMathsInput.preText == null) {
|
|
var pre = "";
|
|
} else {
|
|
var pre = currMathsInput.preText;
|
|
}
|
|
if (un(currMathsInput.postText) || currMathsInput.postText == null) {
|
|
var post = "";
|
|
} else {
|
|
var post = currMathsInput.postText;
|
|
}
|
|
|
|
text = text.slice(0, slicePos) + pre + keyValue + post + text.slice(slicePos);
|
|
|
|
// replace the string
|
|
var evalString = 'currMathsInput.richText'
|
|
for (var i = 0; i < cursorPos.length - 1; i++) {
|
|
// ugly string creation approach in order to use eval()
|
|
evalString += '[' + cursorPos[i] + ']';
|
|
}
|
|
eval(evalString + ' = text;');
|
|
|
|
// if followed by a power, test if a baseSpacer is now required
|
|
if (cursorPos[cursorPos.length - 1] + 1 == text.length && typeof currMathsInput.cursorMap[currMathsInput.cursorPos + 1] !== 'undefined') {
|
|
// get the next element after the parent
|
|
var nextCursorPos = currMathsInput.cursorMap[currMathsInput.cursorPos + 1];
|
|
var nextElem = currMathsInput.richText;
|
|
for (var aa = 0; aa < nextCursorPos.length - 3; aa++) {nextElem = nextElem[nextCursorPos[aa]]};
|
|
if (nextElem[0] == 'power' || nextElem[0] == 'subs') {
|
|
var baseSpacer = true;
|
|
if (/[a-zA-Z0-9)]/g.test(keyValue) == true) baseSpacer = false
|
|
var evalString = 'currMathsInput.richText'
|
|
for (var aa = 0; aa < nextCursorPos.length - 3; aa++) {
|
|
// ugly string creation apprach in order to use eval()
|
|
evalString += '[' + nextCursorPos[aa] + ']';
|
|
}
|
|
eval(evalString + "[1] = " + baseSpacer + ";");
|
|
}
|
|
}
|
|
|
|
mathsInputMapCursorPos();
|
|
currMathsInput.cursorPos += 1;
|
|
mathsInputCursorCoords();
|
|
currMathsInput.preText = '';
|
|
currMathsInput.postText = '';
|
|
}
|
|
}
|
|
}
|
|
|
|
//var date = new Date();
|
|
//var prevMathsInputTime = date.getTime();
|
|
var mathsInputDoubleInput = false;
|
|
|
|
/*function setMathsInputBackColor(input,color) {
|
|
input.backColor = color;
|
|
drawMathsInputText(input);
|
|
}*/
|
|
function measureMathsInputText(input) {
|
|
var leftPoint = 10;
|
|
if (input.textAlign == 'center') {leftPoint = 0.5 * input.data[2]};
|
|
if (typeof input.richText[input.richText.length - 1] !== 'string') {input.richText.push('')};
|
|
return drawMathsText(input.ctx, input.richText, input.fontSize, leftPoint, 0.5 * input.data[3], input.algText, input.textLoc, input.textAlign, 'middle', input.textColor, 'measure');
|
|
}
|
|
function drawMathsInputText(input,ctxLocal,sf,useRelPos) {
|
|
if (typeof sf == 'undefined') sf = 1;
|
|
if (typeof ctxLocal == 'undefined') {
|
|
input.ctx.clearRect(0,0,input.data[102],input.data[103]);
|
|
var ctx = input.ctx;
|
|
var ownCanvas = true;
|
|
} else {
|
|
var ctx = ctxLocal; // will draw to a different canvas
|
|
var ownCanvas = false;
|
|
}
|
|
if (typeof input.richText[input.richText.length-1] !== 'string') {input.richText.push('')};
|
|
var leftPoint = 10*sf;
|
|
var topPoint = 0;
|
|
|
|
if (typeof input.varSize == 'object') {
|
|
if (input.textAlign == 'left') {
|
|
leftPoint = input.varSize.padding*sf;
|
|
if (typeof input.varSize.padding !== 'number') leftPoint = 10*sf;
|
|
} else if (input.textAlign == 'center') {
|
|
leftPoint = 0;
|
|
} else if (input.textAlign == 'right') {
|
|
leftPoint = 0 - input.varSize.padding*sf;
|
|
if (typeof input.varSize.padding !== 'number') leftPoint = -10*sf;
|
|
}
|
|
var minTightWidth = input.varSize.minWidth*sf || 50*sf;
|
|
var minTightHeight = input.varSize.minHeight*sf || 50*sf;
|
|
var padding = input.varSize.padding*sf;
|
|
var maxWidth = input.varSize.maxWidth*sf || input.data[102]*sf;
|
|
var maxHeight = input.varSize.maxHeight*sf || input.data[103]*sf;
|
|
} else {
|
|
if (input.textAlign == 'left') {
|
|
leftPoint = 10*sf;
|
|
} else if (input.textAlign == 'center') {
|
|
leftPoint = 0;
|
|
} else if (input.textAlign == 'right') {
|
|
|
|
}
|
|
var minTightWidth = 50*sf;
|
|
var minTightHeight = 50*sf;
|
|
var padding = 0.01*sf;
|
|
var maxWidth = input.data[102]*sf;
|
|
var maxHeight = input.data[103]*sf;
|
|
}
|
|
|
|
if (input.border == true) {
|
|
if (typeof input.varSize == 'object') {
|
|
var border = {
|
|
type:'tight',
|
|
color:input.backColor,
|
|
borderColor:input.borderColor,
|
|
borderWidth:input.borderWidth*sf,
|
|
dash:input.borderDash,
|
|
radius:input.borderRadius*sf || input.radius*sf || 0
|
|
}
|
|
} else {
|
|
var radius = input.borderRadius*sf || input.radius*sf || 0;
|
|
var borderLeft = input.borderWidth*sf/2;
|
|
var borderTop = input.borderWidth*sf/2;
|
|
if (ownCanvas == false) {
|
|
borderLeft += input.data[100]*sf;
|
|
borderTop += input.data[101]*sf;
|
|
}
|
|
roundedRect(ctx,borderLeft,borderTop,input.data[102]*sf-input.borderWidth*sf,input.data[103]*sf-input.borderWidth*sf,radius,input.borderWidth*sf,input.borderColor,input.backColor,input.borderDash);
|
|
var border = {type:'none'};
|
|
}
|
|
} else {
|
|
var border = {type:'none'};
|
|
}
|
|
|
|
if (ownCanvas == false) {
|
|
if (!isNaN(input.data[100])) {
|
|
leftPoint += input.data[100]*sf;
|
|
topPoint += input.data[101]*sf;
|
|
} else {
|
|
leftPoint += input.data[0]*sf;
|
|
topPoint += input.data[1]*sf;
|
|
}
|
|
if (boolean(useRelPos,true) == true && typeof draw !== 'undefined' && typeof draw !== 'undefined' && typeof draw.drawRelPos !== 'undefined') {
|
|
leftPoint -= draw.drawRelPos[0]*sf;
|
|
topPoint -= draw.drawRelPos[1]*sf;
|
|
}
|
|
}
|
|
|
|
var lineSpacingFactor = input.lineSpacingFactor || 1.2;
|
|
var lineSpacingStyle = input.lineSpacingStyle || 'variable';
|
|
|
|
var drawText = text({
|
|
context:ctx,
|
|
textArray:input.richText,
|
|
left:leftPoint,
|
|
top:topPoint,
|
|
width:maxWidth,
|
|
height:maxHeight,
|
|
allowSpaces:true,
|
|
textAlign:input.textAlign,
|
|
vertAlign:input.vertAlign,
|
|
minTightWidth:minTightWidth,
|
|
minTightHeight:minTightHeight,
|
|
padding:padding,
|
|
box:border,
|
|
sf:sf,
|
|
lineSpacingFactor:lineSpacingFactor,
|
|
spacingStyle:lineSpacingStyle
|
|
});
|
|
|
|
if (ownCanvas == true) {
|
|
input.textLoc = drawText.textLoc;
|
|
input.breakPoints = drawText.breakPoints;
|
|
input.tightRect = drawText.tightRect;
|
|
input.totalTextWidth = drawText.totalTextWidth;
|
|
input.maxWordWidth = drawText.maxWordWidth;
|
|
}
|
|
|
|
/*if (typeof input.drawPath == 'object') {
|
|
if (input.tightRect[3] > input.drawPath.obj[0].height) {
|
|
input.drawPath.obj[0].height = input.tightRect[3];
|
|
input.varSize.maxHeight = input.tightRect[3];
|
|
updateBorder(input.drawPath);
|
|
drawCanvasPaths();
|
|
}
|
|
}*/
|
|
|
|
if (typeof input.varSize == 'object' && ownCanvas == true) {
|
|
// resize cursor canvas
|
|
if (typeof input.tightRect == 'object') {
|
|
input.cursorData[100] = input.data[100] + input.tightRect[0];
|
|
input.cursorData[101] = input.data[101] + input.tightRect[1];
|
|
input.cursorData[102] = input.tightRect[2];
|
|
input.cursorData[103] = input.tightRect[3];
|
|
} else {
|
|
input.cursorData[100] = input.data[100];
|
|
input.cursorData[101] = input.data[101];
|
|
input.cursorData[102] = input.data[102];
|
|
input.cursorData[103] = input.data[103];
|
|
}
|
|
input.cursorCanvas.width = input.cursorData[102];
|
|
input.cursorCanvas.height = input.cursorData[103];
|
|
resizeCanvas(input.cursorCanvas,input.cursorData[100],input.cursorData[101],input.cursorData[102],input.cursorData[103]);
|
|
}
|
|
|
|
if (!un(draw) && draw.drawMode == 'textEdit') {
|
|
var obj = sel();
|
|
if (obj.type == 'text' && obj.mathsInput.canvas == input.canvas) {
|
|
if (input.cursorData[103] > obj.height || input.cursorData[102] > obj.width) {
|
|
for (var i = 0; i < draw.path.length; i++) {
|
|
if (draw.path[i].selected == true) {
|
|
if (input.cursorData[103] > obj.height) obj.height = input.cursorData[103];
|
|
if (input.cursorData[102] > obj.width) obj.width = input.cursorData[102];
|
|
updateBorder(draw.path[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
calcCursorPositions();
|
|
drawSelectCanvas();
|
|
}
|
|
//console.clear();
|
|
//if (currMathsInput.id == 1) console.log(currMathsInput.id,JSON.stringify(currMathsInput.richText));
|
|
}
|
|
function mathsInputAddChar(mInput,char) {
|
|
if (un(mInput)) mInput = currMathsInput;
|
|
// get last position
|
|
var cursorPos = mInput.cursorMap[mInput.cursorMap.length-1];
|
|
var loc = mInput.textLoc;
|
|
for (var aa = 0 ; aa < cursorPos.length; aa++) {
|
|
loc = loc[cursorPos[aa]];
|
|
}
|
|
//console.log(cursorPos);
|
|
|
|
var font,fontSize,color,bold,italic;
|
|
arrayHandler(mInput.richText);
|
|
var newLoc = drawMathsText(mInput.ctx,char,fontSize,loc.left,loc.top+0.5*loc.height,false,[],'left','middle',color,'draw','none',bold,italic,font,false,1).textLoc;
|
|
|
|
var evalString = '';
|
|
for (var aa = 0 ; aa < cursorPos.length-1; aa++) {
|
|
evalString += '['+cursorPos[aa]+']';
|
|
}
|
|
eval('mInput.richText'+evalString+'=mInput.richText'+evalString+'+char');
|
|
eval('mInput.textLoc'+evalString+'.push(newLoc[0][1])');
|
|
cursorPos[cursorPos.length-1]++;
|
|
mInput.cursorMap.push(cursorPos);
|
|
|
|
//console.log(mInput);
|
|
|
|
function markupTag(tag) {
|
|
if (tag.indexOf('<<font:') == 0) {
|
|
font = tag.slice(7,-2);
|
|
} else if (tag.indexOf('<<fontSize:') == 0) {
|
|
fontSize = Number(tag.slice(11,-2));
|
|
} else if (tag.indexOf('<<color:') == 0) {
|
|
color = tag.slice(8,-2);
|
|
} else if (tag.indexOf('<<bold:') == 0) {
|
|
if (tag.indexOf('true') > -1) bold = true;
|
|
if (tag.indexOf('false') > -1) bold = false;
|
|
} else if (tag.indexOf('<<italic:') == 0) {
|
|
if (tag.indexOf('true') > -1) italic = true;
|
|
if (tag.indexOf('false') > -1) italic = false;
|
|
}
|
|
}
|
|
function arrayHandler(arr) {
|
|
//console.log(JSON.stringify(arr));
|
|
for (var i = 0; i < arr.length; i++) {
|
|
if (typeof arr[i] == 'object') {
|
|
arrayHandler(arr[i]);
|
|
} else if (typeof arr[i] == 'string') {
|
|
var splitText = splitMarkup(arr[i]);
|
|
for (var splitElem = 0; splitElem < splitText.length; splitElem++) {
|
|
if (splitText[splitElem].indexOf('<<') == 0 && splitText[splitElem].indexOf('<<br>>') !== 0) {
|
|
markupTag(splitText[splitElem],true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
function createJsString (angleMode) {
|
|
if (typeof angleMode == 'undefined') {
|
|
angleMode = currMathsInput.angleMode || 'deg';
|
|
}
|
|
|
|
var depth = 0;
|
|
var jsArray = [''];
|
|
var js = '';
|
|
var algArray = [''];
|
|
var alg = '';
|
|
var exceptions = ['Math.pow','Math.sqrt','Math.PI','Math.sin','Math.cos','Math.tan','Math.asin','Math.acos','Math.atan','Math.e','Math.log','Math.abs','sin','cos','tan'];
|
|
var position = [0];
|
|
|
|
for (var p = 0; p < currMathsInput.richText.length; p++) {
|
|
//console.log('Before ' + p + ' base element(s):', jsArray);
|
|
subJS(currMathsInput.richText[p],true);
|
|
position[depth]++;
|
|
//console.log('After ' + p + ' base elements:', jsArray);
|
|
}
|
|
|
|
js = jsArray[0];
|
|
alg = algArray[0];
|
|
//console.log(js);
|
|
|
|
function removeAllTagsFromString(str) {
|
|
for (var char = str.length-1; char > -1; char--) {
|
|
if (str.slice(char).indexOf('>>') == 0 && str.slice(char-1).indexOf('>>>') !== 0) {
|
|
for (var char2 = char-2; char2 > -1; char2--) {
|
|
if (str.slice(char2).indexOf('<<') == 0) {
|
|
str = str.slice(0,char2) + str.slice(char+2);
|
|
char = char2;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return str;
|
|
}
|
|
|
|
function subJS(elem, addMultIfNecc) {
|
|
if (typeof addMultIfNecc !== 'boolean') addMultIfNecc = true;
|
|
//console.log('subJS', elem);
|
|
if (typeof elem == 'string') {
|
|
//console.log('string');
|
|
var subText = replaceAll(elem, ' ', ''); // remove white space
|
|
subText = removeAllTagsFromString(subText);
|
|
|
|
subText = subText.replace(/\u00D7/g, '*'); // replace multiplications signs with *
|
|
subText = subText.replace(/\u00F7/g, '/'); // replace division signs with /
|
|
subText = subText.replace(/\u2264/g, '<='); // replace signs with <=
|
|
subText = subText.replace(/\u2265/g, '>='); // replace signs with >=
|
|
for (var c = 0; c < subText.length - 2; c++) {
|
|
if (subText.slice(c).indexOf('sin') == 0 || subText.slice(c).indexOf('cos') == 0 || subText.slice(c).indexOf('tan') == 0) {
|
|
if (subText.slice(c).indexOf('(') == 3) {
|
|
if (angleMode == 'rad') {
|
|
subText = subText.slice(0,c)+'Math.'+subText.slice(c);
|
|
c += 5;
|
|
} else {
|
|
subText = subText.slice(0,c)+'Math.'+subText.slice(c,c+4)+'(Math.PI/180)*'+subText.slice(c+4);
|
|
c += 19;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
subText = timesBeforeLetters(subText);
|
|
// if following frac or power, add * if necessary
|
|
if (addMultIfNecc == true && jsArray[depth] !== '' && elem !== '' && /[ \+\-\=\u00D7\u00F7\u2264\u2265\<\>\])]/.test(elem.charAt(0)) == false) subText = '*' + subText;
|
|
jsArray[depth] += subText;
|
|
algArray[depth] += subText;
|
|
return;
|
|
} else if (elem[0] == 'frac') {
|
|
//console.log('frac');
|
|
var subText = '';
|
|
var subText2 = '';
|
|
// if not proceeded by an operator, put a times sign in
|
|
if (jsArray[depth] !== '' && /[\+\-\u00D7\u00F7\*\/\=\[(]/.test(jsArray[depth].slice(-1)) == false) subText += "*";
|
|
depth++;
|
|
position.push(0);
|
|
jsArray[depth] = '';
|
|
subJS(elem[1], false);
|
|
jsArray[depth] = replaceAll(jsArray[depth], ' ', ''); // remove white space
|
|
subText += '((' + jsArray[depth] + ')/';
|
|
subText2 += 'frac(' + jsArray[depth] + ',';
|
|
jsArray[depth] = '';
|
|
subJS(elem[2], false);
|
|
jsArray[depth] = replaceAll(jsArray[depth], ' ', ''); // remove white space
|
|
subText += '(' + jsArray[depth] + '))';
|
|
subText2 += jsArray[depth] + ')';
|
|
jsArray[depth] = '';
|
|
depth--;
|
|
position.pop();
|
|
jsArray[depth] += subText;
|
|
algArray[depth] += subText2;
|
|
return;
|
|
} else if (elem[0] == 'sqrt') {
|
|
//console.log('sqrt');
|
|
var subText = '';
|
|
var subText2 = '';
|
|
// if not proceeded by an operator, put a times sign in
|
|
if (jsArray[depth] !== '' && /[\+\-\u00D7\u00F7\*\/\=\[(]/.test(jsArray[depth].slice(-1)) == false) subText += "*";
|
|
depth++;
|
|
position.push(0);
|
|
jsArray[depth] = '';
|
|
subJS(elem[1], false);
|
|
jsArray[depth] = replaceAll(jsArray[depth], ' ', ''); // remove white space
|
|
subText += 'Math.sqrt('+ jsArray[depth] +')';
|
|
subText2 += 'sqrt('+jsArray[depth]+')';
|
|
jsArray[depth] = '';
|
|
depth--;
|
|
position.pop();
|
|
jsArray[depth] += subText;
|
|
algArray[depth] += subText2;
|
|
return;
|
|
} else if (elem[0] == 'root') {
|
|
//console.log(elem[0]);
|
|
var subText = '';
|
|
var subText2 = '';
|
|
// if not proceeded by an operator, put a times sign in
|
|
if (jsArray[depth] !== '' && /[\+\-\u00D7\u00F7\*\/\=\[(]/.test(jsArray[depth].slice(-1)) == false) subText += "*";
|
|
depth++;
|
|
position.push(0);
|
|
jsArray[depth] = '';
|
|
subJS(elem[2], false);
|
|
jsArray[depth] = replaceAll(jsArray[depth], ' ', ''); // remove white space
|
|
subText += '(Math.pow('+jsArray[depth]+',';
|
|
subText2 += 'root('+jsArray[depth]+',';
|
|
jsArray[depth] = '';
|
|
subJS(elem[1], false);
|
|
jsArray[depth] = replaceAll(jsArray[depth], ' ', ''); // remove white space
|
|
subText += '(1/('+jsArray[depth]+'))))';
|
|
subText2 += jsArray[depth]+')';
|
|
jsArray[depth] = '';
|
|
depth--;
|
|
position.pop();
|
|
jsArray[depth] += subText;
|
|
algArray[depth] += subText2;
|
|
return;
|
|
} else if (elem[0] == 'sin' || elem[0] == 'cos' || elem[0] == 'tan') {
|
|
//console.log(elem[0]);
|
|
var subText = '';
|
|
// if not proceeded by an operator, put a times sign in
|
|
if (jsArray[depth] !== '' && /[\+\-\u00D7\u00F7\*\/\=\[(]/.test(jsArray[depth].slice(-1)) == false) subText += "*";
|
|
depth++;
|
|
position.push(0);
|
|
jsArray[depth] = '';
|
|
subJS(elem[1], false);
|
|
jsArray[depth] = replaceAll(jsArray[depth], ' ', ''); // remove white space
|
|
var convertText1 = '';
|
|
var convertText2 = '';
|
|
if (angleMode == 'deg' || angleMode == 'degrees') {
|
|
convertText1 = '(';
|
|
convertText2 = ')*Math.PI/180';
|
|
}
|
|
subText += 'Math.'+ elem[0] +'('+convertText1+jsArray[depth]+convertText2+')';
|
|
jsArray[depth] = '';
|
|
depth--;
|
|
position.pop();
|
|
jsArray[depth] += subText;
|
|
algArray[depth] += subText;
|
|
return;
|
|
} else if (elem[0] == 'sin-1' || elem[0] == 'cos-1' || elem[0] == 'tan-1') {
|
|
//console.log(elem[0]);
|
|
var subText = '';
|
|
// if not proceeded by an operator, put a times sign in
|
|
if (jsArray[depth] !== '' && /[\+\-\u00D7\u00F7\*\/\=\[(]/.test(jsArray[depth].slice(-1)) == false) subText += "*";
|
|
depth++;
|
|
position.push(0);
|
|
jsArray[depth] = '';
|
|
subJS(elem[1], false);
|
|
jsArray[depth] = replaceAll(jsArray[depth], ' ', ''); // remove white space
|
|
var convertText1 = '';
|
|
var convertText2 = '';
|
|
if (angleMode == 'deg' || angleMode == 'degrees') {
|
|
convertText1 = '((';
|
|
convertText2 = ')*180/Math.PI)';
|
|
}
|
|
subText += convertText1+'Math.a'+elem[0].slice(0,3)+'('+jsArray[depth]+')'+convertText2;;
|
|
jsArray[depth] = '';
|
|
depth--;
|
|
position.pop();
|
|
jsArray[depth] += subText;
|
|
algArray[depth] += subText;
|
|
return;
|
|
} else if (elem[0] == 'ln') {
|
|
//console.log(elem[0]);
|
|
var subText = '';
|
|
// if not proceeded by an operator, put a times sign in
|
|
if (jsArray[depth] !== '' && /[\+\-\u00D7\u00F7\*\/\=\[(]/.test(jsArray[depth].slice(-1)) == false) subText += "*";
|
|
depth++;
|
|
position.push(0);
|
|
jsArray[depth] = '';
|
|
subJS(elem[1], false);
|
|
jsArray[depth] = replaceAll(jsArray[depth], ' ', ''); // remove white space
|
|
subText += 'Math.log('+jsArray[depth]+')';
|
|
jsArray[depth] = '';
|
|
position.pop();
|
|
depth--;
|
|
jsArray[depth] += subText;
|
|
algArray[depth] += subText;
|
|
return;
|
|
} else if (elem[0] == 'log') {
|
|
//console.log(elem[0]);
|
|
var subText = '';
|
|
// if not proceeded by an operator, put a times sign in
|
|
if (jsArray[depth] !== '' && /[\+\-\u00D7\u00F7\*\/\=\[(]/.test(jsArray[depth].slice(-1)) == false) subText += "*";
|
|
depth++;
|
|
position.push(0);
|
|
jsArray[depth] = '';
|
|
subJS(elem[1], false);
|
|
jsArray[depth] = replaceAll(jsArray[depth], ' ', ''); // remove white space
|
|
subText += '((Math.log('+jsArray[depth]+'))/(Math.log(10)))';
|
|
jsArray[depth] = '';
|
|
depth--;
|
|
position.pop();
|
|
jsArray[depth] += subText;
|
|
algArray[depth] += subText;
|
|
return;
|
|
} else if (elem[0] == 'logBase') {
|
|
//console.log(elem[0]);
|
|
var subText = '';
|
|
// if not proceeded by an operator, put a times sign in
|
|
if (jsArray[depth] !== '' && /[\+\-\u00D7\u00F7\*\/\=\[(]/.test(jsArray[depth].slice(-1)) == false) subText += "*";
|
|
depth++;
|
|
position.push(0);
|
|
jsArray[depth] = '';
|
|
subJS(elem[2], false);
|
|
jsArray[depth] = replaceAll(jsArray[depth], ' ', ''); // remove white space
|
|
subText += '((Math.log('+jsArray[depth]+'))/';
|
|
jsArray[depth] = '';
|
|
subJS(elem[1], false);
|
|
jsArray[depth] = replaceAll(jsArray[depth], ' ', ''); // remove white space
|
|
subText += '(Math.log('+jsArray[depth]+')))';
|
|
jsArray[depth] = '';
|
|
depth--;
|
|
position.pop();
|
|
jsArray[depth] += subText;
|
|
algArray[depth] += subText;
|
|
return;
|
|
} else if (elem[0] == 'abs') {
|
|
//console.log(elem[0]);
|
|
var subText = '';
|
|
// if not proceeded by an operator, put a times sign in
|
|
if (jsArray[depth] !== '' && /[\+\-\u00D7\u00F7\*\/\=\[(]/.test(jsArray[depth].slice(-1)) == false) subText += "*";
|
|
depth++;
|
|
position.push(0);
|
|
jsArray[depth] = '';
|
|
subJS(elem[1], false);
|
|
jsArray[depth] = replaceAll(jsArray[depth], ' ', ''); // remove white space
|
|
subText += 'Math.abs('+jsArray[depth]+')';
|
|
jsArray[depth] = '';
|
|
depth--;
|
|
position.pop();
|
|
jsArray[depth] += subText;
|
|
algArray[depth] += subText;
|
|
return;
|
|
} else if (elem[0] == 'power' || elem[0] == 'pow') {
|
|
//console.log('power');
|
|
|
|
var baseSplitPoint = 0;
|
|
var trigPower = false;
|
|
//if the power is after a close bracket
|
|
if (jsArray[depth] !== '') {
|
|
if (jsArray[depth].charAt(jsArray[depth].length - 1) == ')') {
|
|
var bracketCount = 1
|
|
for (jsChar = jsArray[depth].length - 2; jsChar >= 0; jsChar--) {
|
|
if (jsArray[depth].charAt(jsChar) == ')') {bracketCount++}
|
|
if (jsArray[depth].charAt(jsChar) == '(') {bracketCount--}
|
|
if (bracketCount == 0 && !baseSplitPoint) {
|
|
baseSplitPoint = jsChar;
|
|
break;
|
|
}
|
|
}
|
|
//if the power is after sin, cos or tan
|
|
|
|
} else if (jsArray[depth].slice(jsArray[depth].length-3) == 'sin' || jsArray[depth].slice(jsArray[depth].length-3) == 'coa' || jsArray[depth].slice(jsArray[depth].length-3) == 'tan') {
|
|
trigPower = true;
|
|
//if the power is after a letter
|
|
} else if (/[A-Za-z]/g.test(jsArray[depth].charAt(jsArray[depth].length - 1)) == true) {
|
|
baseSplitPoint = jsArray[depth].length - 1;
|
|
//if the power is after a numerical digit
|
|
} else if (/[0-9]/g.test(jsArray[depth].charAt(jsArray[depth].length - 1)) == true) {
|
|
var decPoint = false;
|
|
for (jsChar = jsArray[depth].length - 2; jsChar >= 0; jsChar--) {
|
|
if (decPoint == false && jsArray[depth].charAt(jsChar) == '.') {
|
|
decPoint = true;
|
|
} else if (decPoint == true && jsArray[depth].charAt(jsChar) == '.') {
|
|
baseSplitPoint = jsChar + 1;
|
|
break;
|
|
} else if (/[0-9]/g.test(jsArray[depth].charAt(jsChar)) == false) {
|
|
baseSplitPoint = jsChar + 1;
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
return ''; // error
|
|
}
|
|
}
|
|
|
|
/*if (trigPower == true) {
|
|
var power = elem[2];
|
|
if (typeof power == 'string') {
|
|
power = removeAllTagsFromString(power);
|
|
console.log(power);
|
|
if (power == '-1') {
|
|
jsArray[depth] = jsArray[depth].slice(0,-3) + 'Math.a' + jsArray[depth].slice(-3);
|
|
} else if (power == '2') {
|
|
|
|
}
|
|
}
|
|
|
|
}*/
|
|
|
|
var base = jsArray[depth].slice(baseSplitPoint);
|
|
jsArray[depth] = jsArray[depth].slice(0, baseSplitPoint);
|
|
depth++;
|
|
position.push(0);
|
|
jsArray[depth] = '';
|
|
subJS(elem[2], false)
|
|
jsArray[depth] = replaceAll(jsArray[depth], ' ', '');
|
|
if (trigPower == true) {
|
|
console.log(jsArray,jsArray[depth-1],jsArray[depth]);
|
|
if (jsArray[depth] == '-1') {
|
|
jsArray[depth-1] = jsArray[depth-1].slice(0,-3) + 'Math.a' + jsArray[depth-1].slice(-3);
|
|
}
|
|
} else {
|
|
var subText = 'Math.pow(' + base + ',' + jsArray[depth] + ')';
|
|
var subText2 = base + '^' + jsArray[depth];
|
|
}
|
|
jsArray[depth] = '';
|
|
depth--;
|
|
position.pop();
|
|
jsArray[depth] += subText;
|
|
algArray[depth] += subText2;
|
|
return;
|
|
} else if (typeof elem == 'object') {
|
|
//console.log('array');
|
|
depth++;
|
|
position.push(0);
|
|
jsArray[depth] = '';
|
|
for (var sub = 0; sub < elem.length; sub++) {
|
|
//console.log('depth:', depth);
|
|
//console.log('Before ' + sub + ' sub element(s):', jsArray);
|
|
subJS(elem[sub], addMultIfNecc);
|
|
//console.log('After ' + sub + ' sub element(s):', jsArray);
|
|
}
|
|
jsArray[depth-1] += jsArray[depth];
|
|
algArray[depth-1] += algArray[depth];
|
|
jsArray[depth] = '';
|
|
depth--;
|
|
position.pop();
|
|
//console.log('endOfArray', jsArray);
|
|
return;
|
|
}
|
|
}
|
|
|
|
function timesBeforeLetters(testText) {
|
|
// find instances of letters - if proceeded by a number, add *
|
|
for (q = 0; q < testText.length; q++) {
|
|
if (q > 0) {
|
|
if (/[a-zA-Z]/g.test(testText.charAt(q)) == true && /[a-zA-Z0-9)]/.test(testText.charAt(q - 1)) == true) {
|
|
testText = testText.slice(0, q) + '*' + testText.slice(q);
|
|
}
|
|
// if an open bracket is proceeded by a letter, number or ), add *
|
|
if (/[\[(]/g.test(testText.charAt(q)) == true && testText.length > q && /[A-Za-z0-9)]/g.test(testText.charAt(q - 1)) == true) {
|
|
testText = testText.slice(0, q) + '*' + testText.slice(q);
|
|
}
|
|
}
|
|
for (var i = 0; i < exceptions.length; i++) {
|
|
if (testText.slice(q).indexOf(exceptions[i]) == 0) {
|
|
q += exceptions[i].length;
|
|
}
|
|
}
|
|
}
|
|
return testText;
|
|
}
|
|
var jsValue;
|
|
try {
|
|
jsValue = eval(js);
|
|
} catch (err) {}
|
|
return js;
|
|
}
|
|
function splitText(text) {
|
|
// find split points in text string
|
|
var splitPointCount = 0;
|
|
var textSplitPoints = [];
|
|
var delimiter = '%&^';
|
|
for (i = 0; i <= text.length; i++) {
|
|
var fracStartPos = text.substring(i, text.length).indexOf('frac(');
|
|
var rootStartPos = text.substring(i, text.length).indexOf('root(');
|
|
var powerStartPos = text.substring(i, text.length).indexOf('power(');
|
|
if (fracStartPos !== -1) {fracStartPos += i};
|
|
if (rootStartPos !== -1) {rootStartPos += i};
|
|
if (powerStartPos !== -1) {powerStartPos += i};
|
|
if (fracStartPos > -1 || rootStartPos > -1 || powerStartPos > -1) {
|
|
textSplitPoints[splitPointCount] = [];
|
|
if (fracStartPos == -1) {fracStartPos = 10000};
|
|
if (rootStartPos == -1) {rootStartPos = 10000};
|
|
if (powerStartPos == -1) {powerStartPos = 10000};
|
|
textSplitPoints[splitPointCount][0] = Math.min(fracStartPos, rootStartPos, powerStartPos);
|
|
var openBracketCount = 0;
|
|
var closeBracketCount = 0;
|
|
for (j = textSplitPoints[splitPointCount][0]; j <= text.length; j++) {
|
|
if (!textSplitPoints[splitPointCount][1]) {
|
|
if (text.charAt(j) == '(') {openBracketCount++};
|
|
if (text.charAt(j) == ')') {closeBracketCount++};
|
|
if (openBracketCount > 0 && (openBracketCount == closeBracketCount)) {
|
|
textSplitPoints[splitPointCount][1] = j;
|
|
i = j;
|
|
}
|
|
}
|
|
}
|
|
splitPointCount++;
|
|
}
|
|
}
|
|
|
|
if (textSplitPoints.length == 0) {return text}
|
|
|
|
for (i = 0; i < textSplitPoints.length; i++) {
|
|
text = text.substring(0, textSplitPoints[i][0] + i * 2 * delimiter.length) + delimiter + text.substring(textSplitPoints[i][0] + i * 2 * delimiter.length, textSplitPoints[i][1] + 1 + i * 2 * delimiter.length) + delimiter + text.substring(textSplitPoints[i][1] + 1 + i * 2 * delimiter.length, text.length);
|
|
}
|
|
var splitArray = text.split(delimiter);
|
|
var returnArray = [];
|
|
for (i = 0; i < splitArray.length; i++) {
|
|
var type = 0;
|
|
if (splitArray[i].indexOf('frac(') == 0) {type = 'frac'};
|
|
if (splitArray[i].indexOf('root(') == 0) {type = 'root'};
|
|
if (splitArray[i].indexOf('power(') == 0) {type = 'power'};
|
|
if (type == 0) {
|
|
if (splitArray[i] !== '') {returnArray.push(splitArray[i])}
|
|
} else {
|
|
var subArray = [];
|
|
subArray[0] = type;
|
|
|
|
var params = splitArray[i].substring(type.length + 1, splitArray[i].length - 1);
|
|
var openBracketCount = 0;
|
|
var closeBracketCount = 0;
|
|
var splitPoint = -1;
|
|
|
|
// find split point of params
|
|
for (j = 0; j <= params.length; j++) {
|
|
if (params.charAt(j) == '(') {openBracketCount++};
|
|
if (params.charAt(j) == ')') {closeBracketCount++};
|
|
if (params.charAt(j) == ',' && (openBracketCount == closeBracketCount) && splitPoint == -1) {
|
|
splitPoint = j;
|
|
}
|
|
}
|
|
subArray[1] = params.substring(0, splitPoint);
|
|
subArray[2] = params.substring(splitPoint + 1, params.length).trim();
|
|
returnArray.push(subArray)
|
|
}
|
|
}
|
|
return returnArray;
|
|
}
|
|
|
|
/*! correcting-interval 2.0.0 | Copyright 2014 Andrew Duthie | MIT License */
|
|
/* jshint evil: true */
|
|
/* usage example:
|
|
var startTime = Date.now();
|
|
setCorrectingInterval(function() {
|
|
console.log((Date.now() - startTime) + 'ms elapsed');
|
|
}, 1000);
|
|
*/
|
|
;(function(global, factory) {
|
|
// Use UMD pattern to expose exported functions
|
|
if (typeof exports === 'object') {
|
|
// Expose to Node.js
|
|
module.exports = factory();
|
|
} else if (typeof define === 'function' && define.amd) {
|
|
// Expose to RequireJS
|
|
define([], factory);
|
|
}
|
|
|
|
// Expose to global object (likely browser window)
|
|
var exports = factory();
|
|
for (var prop in exports) {
|
|
global[prop] = exports[prop];
|
|
}
|
|
}(this, function() {
|
|
// Track running intervals
|
|
var numIntervals = 0,
|
|
intervals = {};
|
|
|
|
// Polyfill Date.now
|
|
var now = Date.now || function() {
|
|
return new Date().valueOf();
|
|
};
|
|
|
|
var setCorrectingInterval = function(func, delay) {
|
|
var id = numIntervals++,
|
|
planned = now() + delay;
|
|
|
|
// Normalize func as function
|
|
switch (typeof func) {
|
|
case 'function':
|
|
break;
|
|
case 'string':
|
|
var sFunc = func;
|
|
func = function() {
|
|
eval(sFunc);
|
|
};
|
|
break;
|
|
default:
|
|
func = function() { };
|
|
}
|
|
|
|
function tick() {
|
|
func();
|
|
|
|
// Only re-register if clearCorrectingInterval was not called during function
|
|
if (intervals[id]) {
|
|
planned += delay;
|
|
intervals[id] = setTimeout(tick, planned - now());
|
|
}
|
|
}
|
|
|
|
intervals[id] = setTimeout(tick, delay);
|
|
return id;
|
|
};
|
|
|
|
var clearCorrectingInterval = function(id) {
|
|
clearTimeout(intervals[id]);
|
|
delete intervals[id];
|
|
};
|
|
|
|
return {
|
|
setCorrectingInterval: setCorrectingInterval,
|
|
clearCorrectingInterval: clearCorrectingInterval
|
|
};
|
|
}));
|
|
function logText(clearConsole) {
|
|
var input = currMathsInput;
|
|
if (clearConsole == true) console.clear();
|
|
console.log('richText:',input.richText);
|
|
console.log('cursorMap:');
|
|
for (var i = 0; i < input.cursorMap.length; i++) {
|
|
var char = input.richText;
|
|
for (var j = 0; j < input.cursorMap[i].length - 1; j++) {char = char[input.cursorMap[i][j]];};
|
|
// check for breakPoints
|
|
var slicePos = input.cursorMap[i][input.cursorMap[i].length-1];
|
|
if (typeof currMathsInput.breakPoints == 'object') {
|
|
var map = currMathsInput.cursorMap[i];
|
|
for (var k = 0; k < currMathsInput.breakPoints.length - 1; k++) {
|
|
var iBreak = currMathsInput.allMap[currMathsInput.breakPoints[k]];
|
|
if (iBreak[0] == map[0] && iBreak[1] < map[1]) {
|
|
slicePos--;
|
|
}
|
|
}
|
|
}
|
|
var char1 = char.slice(slicePos-5,slicePos);
|
|
var char2 = char.slice(slicePos,slicePos+5);
|
|
if (i == input.cursorPos) {
|
|
console.log('>'+i+':',input.cursorMap[i],char1,char2,'<<< cursorPos');
|
|
} else {
|
|
console.log('>'+i+':',input.cursorMap[i],char1,char2);
|
|
}
|
|
}
|
|
}
|
|
function drawTextLocs() {
|
|
for (var loc = 0; loc < currMathsInput.cursorMap.length; loc++) {
|
|
var cursorPos = currMathsInput.cursorMap[loc];
|
|
var evalString = 'currMathsInput.textLoc'
|
|
for (aa = 0; aa < cursorPos.length; aa++) {
|
|
evalString += '[' + cursorPos[aa] + ']';
|
|
}
|
|
var pos = eval(evalString);
|
|
console.log(loc, pos.left);
|
|
currMathsInput.ctx.strokeStyle = '#00F';
|
|
currMathsInput.ctx.lineWidth = 2;
|
|
currMathsInput.ctx.beginPath();
|
|
currMathsInput.ctx.moveTo(pos.left,pos.top);
|
|
currMathsInput.ctx.lineTo(pos.left,pos.top+pos.height);
|
|
currMathsInput.ctx.closePath();
|
|
currMathsInput.ctx.stroke();
|
|
}
|
|
}
|
|
function isMouseOverText(mathsInput) {
|
|
if (typeof mathsInput == 'undefined') mathsInput = currMathsInput;
|
|
var locs = [];
|
|
for (var i = 0; i < mathsInput.cursorMap.length; i++) {
|
|
var textLoc = mathsInput.textLoc;
|
|
for (var j = 0; j < mathsInput.cursorMap[i].length; j++) {textLoc = textLoc[mathsInput.cursorMap[i][j]];};
|
|
locs.push(textLoc);
|
|
}
|
|
var left = mathsInput.data[100];
|
|
var top = mathsInput.data[101];
|
|
for (var i = 0; i < locs.length; i++) {
|
|
if (mouse.x >= left + locs[i].left && mouse.x <= left + locs[i].left + locs[i].width && mouse.y >= top + locs[i].top && mouse.y <= top + locs[i].top + locs[i].height) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
function splitMarkup(element) {
|
|
// seperates markup tags from other text
|
|
var splitAt = [0];
|
|
for (var c = 0; c < element.length; c++) {
|
|
if (element.slice(c).indexOf('<<') == 0 && element.slice(c).indexOf('<<<') !== 0) {
|
|
for (var d = c; d < element.length; d++) {
|
|
if (element.slice(d).indexOf('>>') == 0) {
|
|
splitAt.push(c,d+2);
|
|
break;
|
|
}
|
|
}
|
|
} else if (element.slice(c).indexOf(br) == 0) {
|
|
splitAt.push(c,c+1);
|
|
}
|
|
}
|
|
splitAt.push(element.length);
|
|
var returnArray = [];
|
|
for (var c = 0; c < splitAt.length-1; c++) {
|
|
returnArray.push(element.slice(splitAt[c],splitAt[c+1]))
|
|
}
|
|
return returnArray;
|
|
}
|
|
function reduceTags(textArray) {
|
|
var bold = {value:null,char:true};
|
|
var italic = {value:null,char:true};
|
|
var fontSize = {value:null,char:true};
|
|
var font = {value:null,char:true};
|
|
var color = {value:null,char:true};
|
|
var backColor = {value:null,char:true};
|
|
var align = {set:false};
|
|
var selected = {value:null};
|
|
|
|
function arrayHandler(arr) {
|
|
for (var l = arr.length - 1; l >= 0; l--) {
|
|
if (typeof arr[l] == 'string') {
|
|
arr[l] = stringHandler(arr[l]);
|
|
} else if (typeof arr[l] == 'object') {
|
|
arr[l] = arrayHandler(arr[l]);
|
|
}
|
|
}
|
|
return arr;
|
|
}
|
|
|
|
function stringHandler(string) {
|
|
// first split string into tag and non-tag elements
|
|
var splitString = splitMarkup(string);
|
|
|
|
// work backwards through the string looking for tags
|
|
for (var j = splitString.length - 1; j >= 0; j--) {
|
|
if (splitString[j].indexOf('<<') == 0) {
|
|
for (var k = splitString[j].length; k >= 0; k--) {
|
|
var slice = splitString[j].slice(k);
|
|
if (slice.indexOf('<<bold:') == 0) {
|
|
if (bold.char == false) {
|
|
// no characters between tags - remove
|
|
splitString[j] = splitString[j].slice(0,k)+splitString[j].slice(k+slice.indexOf('>>')+2);
|
|
} else {
|
|
var value = splitString[j].slice(k+7,k+splitString[j].slice(k).indexOf('>>')).toLowerCase();
|
|
if (value == bold.value) {
|
|
// repeated tag - !!
|
|
} else {
|
|
// new tag
|
|
bold.value = value;
|
|
bold.char = false;
|
|
}
|
|
}
|
|
} else if (slice.indexOf('<<italic:') == 0) {
|
|
if (italic.char == false) {
|
|
// no characters between tags - remove
|
|
splitString[j] = splitString[j].slice(0,k)+splitString[j].slice(k+slice.indexOf('>>')+2);
|
|
} else {
|
|
var value = splitString[j].slice(k+9,k+splitString[j].slice(k).indexOf('>>')).toLowerCase();
|
|
if (value == italic.value) {
|
|
// repeated tag
|
|
} else {
|
|
// new tag
|
|
italic.value = value;
|
|
italic.char = false;
|
|
}
|
|
}
|
|
} else if (slice.indexOf('<<fontSize:') == 0) {
|
|
if (fontSize.char == false) {
|
|
// no characters between tags - remove
|
|
splitString[j] = splitString[j].slice(0,k)+splitString[j].slice(k+slice.indexOf('>>')+2);
|
|
} else {
|
|
var value = splitString[j].slice(k+11,k+splitString[j].slice(k).indexOf('>>')).toLowerCase();
|
|
if (value == fontSize.value) {
|
|
// repeated tag
|
|
} else {
|
|
// new tag
|
|
fontSize.value = value;
|
|
fontSize.char = false;
|
|
}
|
|
}
|
|
} else if (slice.indexOf('<<font:') == 0) {
|
|
if (font.char == false) {
|
|
// no characters between tags - remove
|
|
splitString[j] = splitString[j].slice(0,k)+splitString[j].slice(k+slice.indexOf('>>')+2);
|
|
} else {
|
|
var value = splitString[j].slice(k+7,k+splitString[j].slice(k).indexOf('>>')).toLowerCase();
|
|
if (value == font.value) {
|
|
// repeated tag
|
|
} else {
|
|
// new tag
|
|
font.value = value;
|
|
font.char = false;
|
|
}
|
|
}
|
|
} else if (slice.indexOf('<<color:') == 0) {
|
|
if (color.char == false) {
|
|
// no characters between tags - remove
|
|
splitString[j] = splitString[j].slice(0,k)+splitString[j].slice(k+slice.indexOf('>>')+2);
|
|
} else {
|
|
var value = splitString[j].slice(k+8,k+splitString[j].slice(k).indexOf('>>')).toLowerCase();
|
|
if (value == color.value) {
|
|
// repeated tag
|
|
} else {
|
|
// new tag
|
|
color.value = value;
|
|
color.char = false;
|
|
}
|
|
}
|
|
} else if (slice.indexOf('<<backColor:') == 0) {
|
|
if (backColor.char == false) {
|
|
// no characters between tags - remove
|
|
splitString[j] = splitString[j].slice(0,k)+splitString[j].slice(k+slice.indexOf('>>')+2);
|
|
} else {
|
|
var value = splitString[j].slice(k+12,k+splitString[j].slice(k).indexOf('>>')).toLowerCase();
|
|
if (value == backColor.value) {
|
|
// repeated tag
|
|
} else {
|
|
// new tag
|
|
backColor.value = value;
|
|
backColor.char = false;
|
|
}
|
|
}
|
|
} else if (slice.indexOf('<<br>>') == 0 || slice.indexOf(br) == 0) {
|
|
align.set = false;
|
|
} else if (slice.indexOf('<<align:') == 0) {
|
|
if (align.set == false) {
|
|
align.set = true;
|
|
} else {
|
|
// remove tag
|
|
splitString[j] = splitString[j].slice(0,k)+splitString[j].slice(k+slice.indexOf('>>')+2);
|
|
}
|
|
} else if (slice.indexOf('<<selected:') == 0) {
|
|
var value = splitString[j].slice(k+11,k+splitString[j].slice(k).indexOf('>>')).toLowerCase();
|
|
//console.log('selected tag',j,k,value,JSON.stringify(splitString[j]));
|
|
if (value == selected.value) {
|
|
// repeated tag
|
|
} else {
|
|
// new tag
|
|
selected.value = value;
|
|
}
|
|
}
|
|
|
|
}
|
|
} else {
|
|
if (splitString[j].length > 0) {
|
|
bold.char = true;
|
|
italic.char = true;
|
|
fontSize.char = true;
|
|
font.char = true;
|
|
color.char = true;
|
|
backColor.char = true;
|
|
}
|
|
}
|
|
}
|
|
string = '';
|
|
for (var j = 0; j < splitString.length; j++) string += splitString[j];
|
|
return string;
|
|
}
|
|
|
|
if (typeof textArray == 'object') textArray = arrayHandler(textArray);
|
|
//var arrayString = '';
|
|
//console.log('reduceTags()1',JSON.stringify(textArray));
|
|
textArray = combineSpaces2(textArray);
|
|
|
|
// find any adjacent text blocks and combine them
|
|
function combineSpaces2(textArray) {
|
|
if (textArray.length > 1) {
|
|
for (var gg = textArray.length - 1; gg >= 0; gg--) {
|
|
if (typeof textArray[gg] == 'object') {
|
|
//arrayString += '[' + gg + ']';
|
|
combineSpaces2(textArray[gg]);
|
|
} else {
|
|
if (gg < textArray.length - 1 && typeof textArray[gg] == 'string' && typeof textArray[gg+1] == 'string') {
|
|
eval('textArray[' + gg + '] += textArray[' + (gg+1) + ']');
|
|
eval('textArray.splice(gg+1, 1);');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//arrayString = arrayString.slice(0, arrayString.lastIndexOf('[') - arrayString.length);
|
|
return textArray;
|
|
}
|
|
|
|
//console.log('reduceTags()2',JSON.stringify(textArray));
|
|
|
|
return textArray;
|
|
} |