Skip to main content
3-Newcomer
May 13, 2024
Question

MathCAD Prime 10 - Advanced Controls - ES6 JavaScript Methods

  • May 13, 2024
  • 1 reply
  • 1963 views

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.

1 reply

23-Emerald V
October 17, 2024

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

TK4213-NewcomerAuthor
3-Newcomer
October 17, 2024

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:

  1. Add a JSON shim in your _Start function for your Advanced Control
  2. Create a MathCad string in the format of a JSON object literal, except you will have to use something other than double quotes around the labels.  I used single quotes in this example, but any character or substring that isn't used for anything else in the object literal works just as well.  my Object Literal string looks like myJSON:="{'foo': 'hello world'}" in MathCad.
  3. Pass that string as an input to your Advanced Control
  4. Read the input with JScript, use a Regular Expression to globally replace the single quotes with double quotes, then parse it with JSON.parse()

 

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) {
};

 

 

23-Emerald V
October 17, 2024

@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.  

 

2024 10 17 E.png

 

Stuart