Community Tip - Did you get called away in the middle of writing a post? Don't worry you can find your unfinished post later in the Drafts section of your profile page. X
I just got a hold of MCP10 and started playing around with the new Advanced Controls.
It appears that these controls are using Microsoft's Jscript version 5.8. This is semi-equivalent to JavaScript/ES3 which is 11 versions behind the current version. There are a lot of missing features that are commonly used in modern JavaScript, and I would like to at least upgrade to ES6.
I was able to add the methods for working with JSON using this code in the TextBoxEvent_Start function to download and execute the json3 polyfill...
var xhr = new ActiveXObject("Msxml2.XMLHTTP");
xhr.onreadystatechange = function(){ if(xhr.readystate == 4){ eval(xhr.responseText) } }
xhr.open("GET", "https://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js");
xhr.send();
Tangent: Yes, I know eval() is evil, and this opens me up to security risks if cloudflare ever starts sending me something malicious instead of the json3 polyfill. If anyone has a safer solution I am happy to hear it.
...but I haven't been able to get a shim working so I can use other missing methods such as string.includes(), array.find(), etc., etc. I even tried shimming ES5 before I shimmed ES6 but no go... I get the "Object doesn't support this property or method" error at line 18 where I try to use Outputs[0].Value = myString.includes("world");
function TextBoxEvent_Start(Inputs, Outputs) {
var xhr = new ActiveXObject("Msxml2.XMLHTTP");
xhr.onreadystatechange = function(){ if(xhr.readystate == 4){ eval(xhr.responseText) } }
xhr.open("GET", "https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.5.14/es5-shim.min.js");
xhr.send();
xhr.open("GET", "https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.5/es6-shim.min.js");
xhr.send();
};
function TextBoxEvent_Exec(Inputs, Outputs) {
var myString = "Hello world, welcome to the universe.";
Outputs[0].Value = myString.includes("world");
};
function TextBoxEvent_Stop(Inputs, Outputs) {
};
Anyone have any ideas on how I could get ES6 methods working?
Update: ES5 methods work (tried string.trim), just not ES6 methods.
Very interesting. This almost makes JScript worth learning!
However, after just a few minutes of playing around I've encountered several other problems when using a TextBox control.
1. The const keyword isn't supported.
2. String.codepoint() isn't supported.
I don't know how to:
3. Create multiline JScript strings.
4. Create arguments of the form "string": x in Mathcad and pass them to the control. I could play around with parsing inputs, but that rather defeats the point of the exercise.
The control doesn't seem to like nested arrays as an input argument, either - throws an exception with references to a non-existent code line; it doesn't seem to matter is the nested array is regular in shape or irregular.
Perhaps time, the random bashing of keys, and meditation upon a Himalayan mountain top will bring enlightenment ... although, I suspect anoxia is more likely.
Stuart
Yeah, const, [string].codePointAt(), [string].codePointFrom() are all from ES6. You would need to find or write a shim to get that functionality. Unfortunately there doesn't seem to be much in the way of shims for JScript. Some Javascript ones work, but most fail. I haven't found one that includes any functionality above ES5 that works,
I'm not 100% sure what you mean by multiline strings....
To get multiline text output from your JScript you can add a newline character "\n" to your string:
TextBox.Text("This is the first line. \n This is the second line.")
Just make sure that the Multiline box is checked on the Properties tab of your Text Box.
To break a string variable over multiple lines so it is more readable in your script you would type:
myString = "This is multiple lines in your code,";
myString += " but will be returned to the TextBox as one line";
String template literals that use the backtick character in place of the quotes and give you the ability to insert variable values into the string is an ES6 feature and you would need a working shim for that.
As far as passing objects from MathCad to your JScript, I would recommend:
function TextBoxEvent_Start(Inputs, Outputs) {
var xhr = new ActiveXObject("Msxml2.XMLHTTP");
xhr.onreadystatechange = function(){
if(xhr.readystate == 4){
var res = eval(xhr.responseText);
TextBox.Text( TextBox.Text() += "\n" + res )
}
}
xhr.open("GET", "https://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js")
xhr.send();
};
function TextBoxEvent_Exec(Inputs, Outputs) {
var myJSON = Inputs[0].Value
myJSON = myJSON.replace(/'/g,'"')
var myObj = JSON.parse(myJSON);
TextBox.Text(myObj.foo);
};
function TextBoxEvent_Stop(Inputs, Outputs) {
};
@TK421 wrote:
Yeah, const, [string].codePointAt(), [string].codePointFrom() are all from ES6. You would need to find or write a shim to get that functionality. Unfortunately there doesn't seem to be much in the way of shims for JScript. Some Javascript ones work, but most fail. I haven't found one that includes any functionality above ES5 that works,
I'm not 100% sure what you mean by multiline strings....
I meant strings of the form:
var jsonText = `{
"browsers": {
"firefox": {
"name": "Firefox",
"pref_url": "about:config",
"releases": {
"1": {
"release_date": "2004-11-09",
"status": "retired",
"engine": "Gecko",
"engine_version": "1.7"
}
}
}
}
}`;
From the next part of your message, am I right in thinking that is an example of a string template literal that uses the backtick character?
I shall read the rest of your message carefully and see what I can do. My Javascript knowledge is pretty minimal as I've never had much cause to use it.
@TK421 wrote:
To get multiline text output from your JScript you can add a newline character "\n" to your string:
TextBox.Text("This is the first line. \n This is the second line.")
Just make sure that the Multiline box is checked on the Properties tab of your Text Box.
To break a string variable over multiple lines so it is more readable in your script you would type:
myString = "This is multiple lines in your code,"; myString += " but will be returned to the TextBox as one line";
Yes, I already do that, thanks. However, LF didn't consistently appear in a string returned from a control.
Interestingly, LF, CR, and TAB work as you might expect hope when viewing Mathcad strings.
Stuart
That nested array thing is pretty weird. Even if you have no code whatsoever it gives an error on a non-existent line. You would think that PTC would catch that error and return a message that is descriptive of the fact that they haven't implemented that functionality.
My first thought for a work-around would be to use a program in MathCad to convert the nested array into a JScript Array Literal string and then JSON.parse to get the values - just like with the Object Literal string.
@TK421 wrote:
That nested array thing is pretty weird. Even if you have no code whatsoever it gives an error on a non-existent line. You would think that PTC would catch that error and return a message that is descriptive of the fact that they haven't implemented that functionality.
Yes, passing complex data structures into an advanced control must surely be a necessity for many use cases? Passing strings into a control and then parsing them smacks entirely too much of buy dog, bark self syndrome ..,
@TK421 wrote:
My first thought for a work-around would be to use a program in MathCad to convert the nested array into a JScript Array Literal string and then JSON.parse to get the values - just like with the Object Literal string.
... although using JSON methods should let me bark-share with the "dog".
Converting a nested array to a string is worth trying. I have an old M11..15 worksheet that has a string parser for interpreting Matlab arrays. I might even be able to find it some year soon!
Stuart