summaryrefslogtreecommitdiff
path: root/js/dojo/dojox/calc/_ExecutorIframe.html
diff options
context:
space:
mode:
Diffstat (limited to 'js/dojo/dojox/calc/_ExecutorIframe.html')
-rw-r--r--js/dojo/dojox/calc/_ExecutorIframe.html525
1 files changed, 525 insertions, 0 deletions
diff --git a/js/dojo/dojox/calc/_ExecutorIframe.html b/js/dojo/dojox/calc/_ExecutorIframe.html
new file mode 100644
index 0000000..0d2cac5
--- /dev/null
+++ b/js/dojo/dojox/calc/_ExecutorIframe.html
@@ -0,0 +1,525 @@
+<html><head>
+<script type="text/javascript">
+Array.prototype._toString = Array.prototype.toString;
+Array.prototype.toString = function(){ return "[" + this._toString() + "]"; };
+
+Number.prototype._toString = Number.prototype.toString;
+Number.prototype.toString = function(radix){ if(!radix || radix==10){ return ""+this._toString() } if(radix==2){ return "0b"+this._toString(radix); } if(radix==8){ return "0o"+this._toString(radix); } if(radix==16){ return "0x"+this._toString(radix); } return this._toString(radix) + "#" + radix._toString(); };
+
+(function(){ // env is private
+ parseFloat = function(str){
+ var obj = null;
+ function getRadixObject(whole, numberStr, base){
+ obj = {number:numberStr, radix:base};
+ return "";
+ }
+ function getBaseString(whole, base, numberStr){
+ var baseNum = (base == '0b') ? 2 : (base == '0o') ? 8 : 16;
+ return numberStr+"#"+baseNum;
+ }
+
+
+ var str = str.replace(/(0b|0o|0x)(([0-9a-zA-Z]+\.[0-9a-zA-Z]*|\.[0-9a-zA-Z]+|[0-9a-zA-Z]+))/, getBaseString);
+
+ var radix;
+
+ var poundRegExp = /([0-9a-zA-Z]+\.[0-9a-zA-Z]*|\.[0-9a-zA-Z]+|[0-9a-zA-Z]+)\#([0-9a-zA-Z]+)/g;
+ if(poundRegExp.test(str)){
+ // define obj in getRadixObject
+ str.replace(poundRegExp, getRadixObject);
+ radix = obj.radix;
+ str = obj.number;
+ }
+ if(!radix){
+ radix = 10;
+ }
+ var decimal = str.indexOf('.');
+ if(decimal>=0){
+ var left = str.substring(0,decimal);
+ if(left == ""){
+ left = "0";
+ }
+ var right = str.substring(decimal+1, str.length);
+ if(right == ""){
+ right = "0";
+ }
+ var num = parseInt(left, radix);
+
+ var dec = parseInt(right, radix);
+ var length = dec._toString().length;
+ dec /= Math.pow(radix, right.length);
+ return num+dec;
+ }
+ return parseInt(str, radix);
+};
+
+ var env = {
+ window: undefined, "delete": undefined, "new": undefined, // invalidate access to the globals for security so that window.blah is invalid as is delete window
+
+ prompt: function(label, defaultValue){
+ // summary
+ // prompt the user for input without making IE8 mad.
+ // params
+ // label: the String name of the variable you are asking the user to input
+ // defaultValue: primitive, the prompt will show this value initially
+
+ label = label || '';
+ defaultValue = defaultValue || '';
+ try{
+ return this.outerPrompt(label, defaultValue);
+ }catch(e){
+ return window.prompt(label, defaultValue);
+ }
+ },
+ val: function(local, name, obj){
+ // summary
+ // allow the user to use locals, globals, or give input for undefined values
+ // params:
+ // local, a primitive object, is what value might've been passed to val as a local parameter.
+ // name is the String name of the object. It is passed to see if there is an available global or to set the global.
+ var objValue = obj[name];
+ local = (objValue == undefined) ? (local == undefined ? window[name] : local) : objValue ;
+
+ if(typeof local == 'undefined'){
+ if(obj.graphing){
+ return undefined;
+ }
+ local=this.prompt('Enter the value for ' + name, undefined, name);
+
+ return local == null ? undefined : (isNaN(Number(local)) ? local : Number(local));
+ }
+ return local;
+ },
+ _makeKeywordsLiteral: function (text){
+ // summary
+ // surround reserved words with hex characters
+ // ==, then >=. the <=, then !=, then = and surround them with \x0n first
+ text = text.replace(/(!=(?!=)|==|>=|<=|=)/g, "\x02$1\x02");
+ return text.replace(/\b(abstract|boolean|break|byte|case|catch|char|class|const|continue|debugger|default|do|double|else|enum|export|extends|false|final|finally|float|for|function|goto|if|implements|import|in| instanceof|int|interface|long|native|null|package|private|protected|public|return|short|static|super| switch|synchronized|this|throw|throws|transient|true|try|typeof|var|void|volatile|while|with)\b/g, "\x02$1\x02");
+ },
+ switchToGermanNumbers: function(text){
+ // summary
+ // change the format of some javascript allowed numbers to an alternate form 3.5 goes to 3,5
+ var num = 0;
+ var numbers = [];
+ function substituteCommas(whole, junk, text){
+ numbers['_'+num+'_'] = text.replace(/\,/g, ';');
+ return junk+'_'+(num++)+'_';
+ }
+ function substituteNumbers(wholematch, stuff, junk, text, stuff2){
+ return stuff+numbers[text]+stuff2;
+ }
+ if(typeof text != "string"){
+ text = text.toString();
+ }
+ if(text.indexOf('\x02')<0){
+ text = this._makeKeywordsLiteral(text);
+ //text = text.replace(/(!=(?!=)|==|>=|<=|=)/g, "\x02$1\x02");
+ }
+
+ // same as semiColonRegExp
+ var commaRegExp = /([^\x02\s]*)(\([^\(\)]+\)|\[[^\[\]]+\])/;
+ while(commaRegExp.test(text)){
+ text = text.replace(commaRegExp , substituteCommas);
+ }
+
+ while(/((\W)*)(\_[0-9]+\_)((\W)*)/.test(text)){
+ text = text.replace(/((\W)*)(\_[0-9]+\_)((\W)*)/g, substituteNumbers);
+ }
+
+ text = text.replace(/([0-9]*)\.([0-9]+)/g, "$1"+','+"$2");
+
+ // get rid of keyword characters (duplicate code from parse())
+ return text.replace(/\x02((.|\s)*?)\x02/g, "$1");
+ },
+ normalizeTextLanguage: function(text){
+ // summary
+ // change text to use javascript list separators and decimal points instead of commas
+ // params
+ // text is a string like "pow(3,1; 4);"
+ // for that input, this method should return "pow(3.1, 4);"
+
+ var num = 0;
+ var numbers = [];
+ function substituteSemicolons(whole, junk, text){
+ numbers['_'+num+'_'] = text.replace(/\;/g, ',');
+ return junk+'_'+(num++)+'_';
+ }
+ function substituteNumbers(wholematch, stuff, junk, text, stuff2){
+ return stuff+numbers[text]+stuff2;
+ }
+ if(text.indexOf('\x02')<0){
+ text = this._makeKeywordsLiteral(text);
+ }
+ // change all comma-type decimals into periods
+ text = text.replace(/([0-9]*)\,([0-9]+)/g, "$1"+'.'+"$2");
+ //alert(text);
+ var semiColonRegExp = /([^\x02\s]*)(\([^\(\)]+\)|\[[^\[\]]+\])/; // /([^\x02\s]+)(\([^\(\)]+\)|\[[^\[\]]+\])/; // /[^\x02\s]+\([^\(\)]+\)|[^\x02\s]+\[[^\[\]]+\]/; // /[^\x02]\s*\([^\(]+\)/;
+ while(semiColonRegExp.test(text)){
+ text = text.replace(semiColonRegExp, substituteSemicolons);
+ }
+ while(/((\W)*)(\_[0-9]+\_)((\W)*)/.test(text)){
+ text = text.replace(/((\W)*)(\_[0-9]+\_)((\W)*)/g, substituteNumbers);
+ }
+ // get rid of keyword characters (duplicate code from parse())
+ return text.replace(/\x02((.|\s)*?)\x02/g, "$1");
+ },
+ preparse: function(text){
+ // summary
+ // change the numbers to javascript allowed numbers if it is from a different locale
+ if(!this.isJavaScriptLanguage){
+ text = this.normalizeTextLanguage(text);
+ }
+ return text;
+ },
+ // parseFloat(Number(4.5).toString(3)) should return 4.5
+
+ postparse: function(text){
+ // summary
+ // make the javascript numbers match the locale
+ if(!this.isJavaScriptLanguage){
+ text = this.switchToGermanNumbers(text);
+ }
+ return text;
+ },
+ toDecimalRegExp: function(whole, base, number){
+ // summary
+ // get the decimal number from a float
+ function getBase(base){
+ switch(base){
+ case '0b':
+ return 2;
+ case '0o':
+ return 8;
+ case '0x':
+ return 16;
+ default:
+ return 10;
+ }
+ }
+ //return parseInt(base, getBase(base));
+ return parseFloat(base+number);
+ },
+ parse: function(text){
+ // summary
+ // This parses augmented mathematical syntax and converts it to executable JavaScript.
+ // params:
+ // text should be a String which represents an expression, a function, a number, etc
+ //
+ // this array holds the substitutions that represent an expression's parentheses and functions in a simplified way.
+ var numbers = [],
+ // characters
+ functionContentsChar = '\x03',
+ // these are the regular expression needed to find and replace operators
+ factorialRE = /((\w|\.)+)\s*\!/,
+ unaryRightsideRE = /(^|[\+\-\/\*\!\^\u221A]+\s*)([\+\-]+)\s*((\w|\.)+)(?!.*[\+\-])/,
+ unaryRE = /(^|[^a-zA-Z0-9_\.\s]+\s*)([\+\-]+|\u221A)\s*((\w|\.)+)/, // /(^|[^a-zA-Z0-9_\.]\s*)([\+\-]+|\u221A)\s*((\w|\.)+)/,
+ caretRE = /((\w|\.)+)\s*([\^])\s*((\w|\.)+)/, // /((\w|\.)+)\s*([\^])\s*(-?\s*(\w|\.)+)/,
+ radicalRE = /((\w|\.)+)\s*(\u221A)\s*([+-]?\s*(\w|\.)+)/, // /((\w|\.)+)\s*(\u221A)\s*([+-]?\s*(\w|\.)+)(?!.*\u221A)/,
+ binaryHighRE = /((\w|\.)+)\s*([*/])\s*((\w|\.)+)/,
+ binaryLowRE = /((\w|\.)+)\s*([\+\-])+\s*((\w|\.)+)/;
+
+ // get rid of all new and delete statements
+ text = exterminateNewAndDelete(text);
+ // make all keywords and operators literal (like '!=' or 'return') by surrounding them with unprintable characters
+ text = this._makeKeywordsLiteral(text);
+
+
+ function getBaseTen(whole, numberStr, base){
+ return ""+parseFloat(numberStr+"#"+parseInt(base));
+ }
+ text = text.replace(/(0b)([0-1]+\.[0-1]*|\.[0-1]+|[0-1]+)/g, this.toDecimalRegExp);
+ text = text.replace(/(0o)([0-7]+\.[0-7]*|\.[0-7]+|[0-7]+)/g, this.toDecimalRegExp);
+ text = text.replace(/(0x)([0-9a-zA-Z]+\.[0-9a-zA-Z]*|\.[0-9a-zA-Z]+|[0-9a-zA-Z]+)/g, this.toDecimalRegExp);
+
+ text = text.replace(/([0-9a-zA-Z]+\.[0-9a-zA-Z]*|\.[0-9a-zA-Z]+|[0-9a-zA-Z]+)\#([0-9a-zA-Z]+)/g, getBaseTen);
+
+ // parse the input to form JavaScript
+ return MathParser(text);
+
+ function MathParser(text){
+ // Pi is better represented by \u03C0, but isn't computable
+ text = text.replace(/\u03C0/g,"Math.PI");
+ text = text.replace(/\u03F5/g,"Math.E");
+
+ // Microsoft word will give you these '\u2013' for a subtraction sign sometimes, so I'll fix that here
+ text = text.replace(/\u2013/g, "-");
+ // add unreadable characters in front of functions so it is easier to manipulate
+ text = text.replace(/(((\w|\.)+\s*)\()/g,putFuncChar);
+
+ // change 10e-10 or 10e10 or 10e+10 to an constant right away
+ text = scientificNotationSimplifier(text);
+ // recursively track down and replace all simplified parts of the expression until everything is simple; then move the simple text into the correct JavaScript format
+ text = parseRecursive(text);
+ // now resubstitute the real text back into the string now that it is arranged correctly
+ while (hasArrayIndexBasedOnUnderscore(text)){
+ text = text.replace(/\_(\d+)\_/g, function(whole, one){return numbers[parseInt(one)]});
+ }
+ // get rid of the function character from the functions now
+ text = text.replace(/\x01/g,"");
+ // get rid of keyword characters too
+ text = text.replace(/\x02((.|\s)*?)\x02/g, "$1");
+ return text;
+ }
+ function exterminateNewAndDelete(text){
+ return text.replace(/\b(delete|new|this\.*)\b/, "");
+ }
+ // A simple grouping has no parentheses inside the initial pair.
+ function isSimpleGrouping(text){
+ return (/^\([^()]*\)|\W\([^()]*\)/).test(text);
+ }
+ function ReplaceSimpleGrouping(text){
+ return text.replace((/(^|\W)(\([^()]*\))/), replaceWithNum);
+ }
+ function replaceWithNum(wholeMatch, partMatch1, partMatch2){
+ numbers.push(partMatch2);
+ return partMatch1+"_"+(numbers.length-1)+"_";
+ }
+ function replaceFuncWithNum(wholeMatch){
+ numbers.push(wholeMatch);
+ return "_"+(numbers.length-1)+"_";
+ }
+ // A simple function has no parentheses within its parentheses, and has the special character \x01 leading up to the name and (...)
+ function isSimpleFunction(text){
+ return (/\x01((\w|\.)+\s*)\([^()]*\)/).test(text);
+ }
+ function ReplaceSimpleFunction(text){
+ return text.replace(/\x01((\w|\.)+\s*)\([^()]*\)/, replaceFuncWithNum);
+ }
+ function FactorialParser(text){
+ // loop this untill all ! are gone (in main)
+ return text.replace(factorialRE, "\x01"+"factorial($1)");
+ }
+ function putFuncChar(wholematch){
+ return '\x01'+wholematch;
+ }
+ function putInPiece(wholematch){
+ return numbers[currentNum];
+ }
+
+ function caretParser(text){
+ return text.replace(caretRE, replaceBinaryOp);
+ }
+ // the unary radical is inside the unaryOperatorParse(text) function
+ function radicalOperatorParse(text){
+ return text.replace(radicalRE, replaceBinaryOp);
+ }
+ function replaceBinaryOp(wholeMatch, operand1, nothing1, operator, operand2){
+
+ switch(operator.charAt(0)){
+ case '^':
+ return "\x01"+"pow("+operand1+","+operand2+")";
+ case '\u221A':
+ return "\x01"+"pow("+operand2+", 1/"+operand1+")";
+ case '*':
+ case '/':
+ return replaceFuncWithNum(wholeMatch);
+ case '+':
+ case '-':
+ case 'e':
+ return replaceFuncWithNum(simplifyPlusAnsMinus(wholeMatch));
+ }
+ }
+ // e is treated as a binary operator
+ function scientificNotationSimplifier(text){
+ //return text.replace(/((\w|\.)+)\s*([\e])\s*([+-]*\s*(\w|\.)+)/g, replaceBinaryOp);
+ return text.replace(/(([0-9]+\.?[0-9]*))(e)([+-]*([0-9]+))/g, replaceBinaryOp);
+ }
+ // this handles * and /
+ function binaryHighPriorityOperatorParse(text){
+ return text.replace(binaryHighRE, replaceBinaryOp);
+ }
+ // this handles + and - with two operands
+ function binaryLowPriorityOperatorParse(text){
+ return text.replace(binaryLowRE, replaceBinaryOp);
+ }
+ // this replaces the one operand +'s, -'s, and radicals
+ function replaceUnaryOp(wholeMatch, garbage, operator0, operand0){
+ // see what operator it is
+ switch(operator0.charAt(0)){
+ case '\u221A':
+ return garbage+"\x01"+"sqrt("+operand0+")";
+ case '+':
+ case '-':
+ return garbage+replaceFuncWithNum(simplifyPlusAnsMinus(wholeMatch.substr(garbage.length)));
+ }
+ }
+ // this handles one operand operators -, +, radical
+ function unaryOperatorParse(text){
+ return text.replace(unaryRE, replaceUnaryOp);
+ }
+ // this handles one operand operators on the right side of everything
+ function unaryOperatorRightsideParse(text){
+ return text.replace(unaryRightsideRE, replaceUnaryOp);
+ }
+ function parseRecursive(text){
+ // keep going until there is nothing left that can be simplified
+ while (isSimpleGrouping(text)||isSimpleFunction(text)||factorialRE.test(text)||caretRE.test(text)||radicalRE.test(text)||unaryRE.test(text)||binaryHighRE.test(text)||binaryLowRE.test(text)){
+
+ var sTextOrginal = text;
+
+ if(isSimpleFunction(text)){
+ var debugText = text;
+
+ text = ReplaceSimpleFunction(text);
+ var s = numbers[numbers.length-1],
+ pL = s.indexOf("("),
+ funcName = s.substring(s.indexOf("\x01")+1, pL),//take out the function character
+ content = s.substring(pL+1, s.length-1);
+
+ numbers[numbers.length-1] = funcName+"("+parseRecursive(functionContentsChar+content)+")";
+ continue;
+ }
+ if(isSimpleGrouping(text)){
+ text = ReplaceSimpleGrouping(text);
+ var s = numbers[numbers.length-1],
+ content = s.substring(1, s.length-1);
+ numbers[numbers.length-1] = "("+parseRecursive(content)+")";
+ continue;
+ }
+
+ // factorials must come first for 5^2! cases, it equals 25
+ text = FactorialParser(text);
+ if(text!=sTextOrginal){
+ continue;
+ }
+
+ text = caretParser(text);
+ if(text!=sTextOrginal){
+ continue;
+ }
+
+ text = radicalOperatorParse(text);
+ if(text!=sTextOrginal){
+ continue;
+ }
+ text = unaryOperatorRightsideParse(text);
+ if(text!=sTextOrginal){
+ // put parentheses around the unary operators so 0--2 will pass
+ numbers[numbers.length-1] = "("+numbers[numbers.length-1]+")";
+ continue;
+ }
+ text = unaryOperatorParse(text);
+ if(text!=sTextOrginal){
+ // put parentheses around the unary operators so 0--2 will pass
+ numbers[numbers.length-1] = "("+numbers[numbers.length-1]+")";
+ continue;
+ }
+
+ text = binaryHighPriorityOperatorParse(text);
+ if(text!=sTextOrginal){
+ continue;
+ }
+ text = binaryLowPriorityOperatorParse(text);
+ if(text!=sTextOrginal){
+ continue;
+ }
+ // it should never ever make it to this point. If it does, I'll want to know about it.
+ throw("Parse Error");
+ }
+ // make assignments within function calls be arranged to be (x=y, undefined)
+ if(text.charAt(0) == functionContentsChar){
+ text = text.substring(1, text.length);
+ if(text.indexOf('=') >= 0){
+ text = ReplaceFunctionContentAssignments(text);
+ }
+ }
+
+ return text;
+ }
+ function ReplaceFunctionContentAssignments(text){
+ return text.replace(/((\w|\.)+)\x02=\x02((\w|\.)+)/g, "("+"$1"+'\x02=\x02'+"$3"+", {_name:'"+"$1"+"', _value:"+"$3"+"})");
+ }
+ function hasArrayIndexBasedOnUnderscore(text){
+ return /\_\d+\_/.test(text);
+ }
+
+ function simplifyPlusAnsMinus(text){
+ function hasUnsimplifiedPlusMinus(text){
+ return /\-\s*\-/.test(text)||/\+\s*\+/.test(text)||/\+\s*\-/.test(text)||/\-\s*\+/.test(text);
+ }
+ while(hasUnsimplifiedPlusMinus(text)){
+ text = text.replace(/((\-\s*\-)|(\+\s*\+))/g, "+");
+ text = text.replace(/((\+\s*\-)|(\-\s*\+))/g, "-");
+ }
+ return text;
+ }
+
+ },
+ eval: function(text){
+ // summary
+ // create an anonymous function to run the code the parser generates from the user input.
+ // params
+ // text, type String, is the user input that needs to be parsed
+ // this try catch is necessary to ensure that any incorrect input will receive NaN (it won't cause a self destruct from a user typo)
+ try{
+ var value = this.Function(undefined, '', 'return ' + text).call(this); // make sure it is called within the correct scope.
+ //value = ((value instanceof Array || typeof value == "array") ? ("["+value+"]") : value.toString())
+ return this.postparse(value);
+ }catch(e){
+ return NaN;
+ }
+ },
+ normalizedFunction: function(name, args, body){
+ // summary
+ // create an anonymous function to run the code the parser generates from the user input.
+ // params
+ // name: this argument is simply a String that represents the name of the function being evaluated. It can be undefined, but in that case the function is a one time use.
+ // args: the function arguments (a String)
+ // body: the function body, also a String
+ var argMultiVals = '',
+ // make an array of parameters with what's given (if nothing is given, make an empty array)
+ params = args ? (args||'').split(/\W+/) : [];
+
+ argMultiVals += 'var _localObjectContainer = {};\n'+
+ 'for(var _objCnt = 0; _objCnt < arguments.length; _objCnt++){\n'+
+ 'if(typeof arguments[_objCnt] == "object" && "_name" in arguments[_objCnt] && "_value" in arguments[_objCnt]){\n'+
+ '_localObjectContainer.graphing = arguments[_objCnt]._graphing;\n'+
+ '_localObjectContainer[arguments[_objCnt]._name]=arguments[_objCnt]._value;\n'+
+ 'arguments[_objCnt]=undefined;\n}\n}\n';
+
+ // make the parameters fit into the val function so it can use either globals, locals, or if all are null, prompt the user for input
+ for(var i=0; i < params.length; i++){
+ var param = params[i];
+ argMultiVals += param + '=val(' + param + ',"' + param + '", _localObjectContainer);\n';
+ argMultiVals += 'if(typeof '+param+' == "undefined"){\n'+
+ 'return null;}\n';
+ }
+ var _f_ = window.Function.apply(this,
+ [
+ args,
+ 'with(Math){with(this.dojox.math){with(this){\n' +
+ argMultiVals +
+ this.parse(body) +
+ '\n}}}'
+ ]
+ );
+ if(name){
+ return this[name] = _f_;
+ }
+ return _f_;
+ },
+ Function: function(name, args, body){
+ // summary
+ // create an anonymous function to run the code the parser generates from the user input. It also normalizes the language format.
+ // params
+ // name: this argument is simply a String that represents the name of the function being evaluated. It can be undefined, but in that case the function is a one time use.
+ // args: the function arguments (a String)
+ // body: the function body, also a String
+
+ body = this.preparse(body);
+ return this.normalizedFunction(name, args, body);
+
+ }
+ };
+ for(var i in window){
+ if(!(i in env) && i != "alert" && i != "confirm"){ env[i] = undefined; } // invalidate access to the window object's attributes for security so that document.blah is invalid
+ }
+ frameElement.onload(env);
+})();
+</script>
+</head><body>
+<script type="text/javascript">
+ document.documentElement.removeChild(document.documentElement.firstChild); // remove HEAD to remove debugger access for extra security
+</script>
+</body></html>