How to generate blocks from code in blockly? - javascript

I have a blockly application which generates some output code. Now, is it possible to write some function which will take my output code and will put corresponding blocks on workspace.
For example, on this page, https://developers.google.com/blockly/
Blocks are connected to generate javascript code, But is there any way, I will give javascript code and blocks will appear on workspace.

You can only create javascript from blocks, not blocks from javascript. However, You can export blocks to xml, and import back the xml to blocks. So you can always save your blocks anywhere you wish in xml format, and load those from xml back to your blockly workspace.
function saveBlocks() {
var xmlDom = Blockly.Xml.workspaceToDom(Blockly.mainWorkspace);
var xmlText = Blockly.Xml.domToPrettyText(xmlDom);
// do whatever you want to this xml
}
function loadBlock(xml) { // xml is the same block xml you stored
if (typeof xml != "string" || xml.length < 5) {
return false;
}
try {
var dom = Blockly.Xml.textToDom(xml);
Blockly.mainWorkspace.clear();
Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, dom);
return true;
} catch (e) {
return false;
}
}

We are working on a python-to-blocks system here
https://www.npmjs.com/package/#pi-top/blockly
it's a work in progress but pretty much deals with all of Python and is being built to work with the pi-top project website https://further.pi-top.com/ but you should be able to extract something useful, the main code->blocks functionality is in the
src/piBlocks folder. The code is based on this project https://github.com/blockpy-edu/BlockMirror I mainly converted it to typescript, reorganised the code and linted it, with a few additions and bugfixes.

It can be done - see https://makecode.microbit.org/. If you create a block then edit as Javascript, you can edit and (if it's valid code) then it will show the correct blocks when you switch back to the block view. The javascript is a bit odd that it's generates - so don't expect it to turn any javascript into blocks...
This isn't part of Blockly - and I'm not sure how this has been done - just that it exists - hope this helps.

I don't remember seeing this feature in blockly, but it is definitely possible. You will have to write custom parsers for your language code and then build the blocks accordingly.
This was somewhat explored in this answer.
Basically as and when you parse the code, you need to programatically create the blocks and attach them together to create the program in blockly.

Related

How do you use an npm package with require & module export as a plain JS library

I'm not sure I'm even asking the right question here, sorry, but I think the two general ones are:
In what way do you need to modify a node.js package using require etc to be used as a plain embedded script/library in HTML?
How do you call a class constructor (?) in JS as a function to validate a form field?
I'm trying to use this small JS library NoSwearingPlease (which is an npm package) in an environment with no node or build system – so I'm just trying to call it like you would jQuery or something with a script & src in the HTML, and then utilise it with a small inline script.
I can see a couple of things are required to get this working:
the JSON file needs to be called in a different way (not using require etc)
the checker variable needs to be rewritten, again without require
I attempted using jQuery getJSON but I just don't understand the class & scope bits of the library enough to use it I think:
var noswearlist = $.getJSON( "./noswearing-swears.json" );
function() {
console.log( "got swear list from inline script" );
})
.fail(function() {
console.log( "failed to get swear list" );
})
noswearlist.done(function() {
console.log( "done callback as child of noswearlist variable" );
var checker = new NoSwearing(noswearlist);
console.log(checker);
});
Please halp. Thanks!
No need to modify, when outside of node the class is just appended to window (global):
fetch("https://cdn.jsdelivr.net/gh/ThreeLetters/NoSwearingPlease#master/swears.json").then(response => {
return response.json();
}).then(data => {
var noSwearing = new NoSwearing(data);
console.log(noSwearing.check("squarehead"));
});
<script src="https://cdn.jsdelivr.net/gh/ThreeLetters/NoSwearingPlease#master/index.js"></script>
In the future, you can answer this type of question on your own by looking through the source code and looking up things you don't understand. That being said, here's what I was able to gather doing that myself.
For your first question, if you have no build tools you can't use require, you have to hope your NPM package supports adding the class to the window or has a UMD export (which in this case, it does). If so, you can download the source code or use a CDN like JSDelivr and add a <script> tag to link it.
<script src="https://cdn.jsdelivr.net/gh/ThreeLetters/NoSwearingPlease#master/index.js"></script>
I'm having a hard time deciphering your script (it has a few syntax errors as far as I can tell), so here's what you do if you have a variable ns containing the JSON and the string str that you need to check:
var checker = new NoSwearing(ns);
checker.check(str);
As an aside, you should really use build tools to optimize your bundle size and make using packages a lot easier. And consider dropping jQuery for document.querySelector, fetch/XMLHttpRequest, and other modern JavaScript APIs.

How to pass a json object from a Python function to Javascript with Eel where you can use and manipulate the json

This question may be a bit confusing, so let me give you some background. Eel is a Python module where you can take functions made in Python and use them in Javascript, and vice versa. What I want to do is take a json made from a Python function, put it in Javascript, and make a table based on the json that was taken from the Python side. Here's an example.
python.py
def json_example():
json = [
{
"key": "value1"
},
{
"key": "value2"
}
]
return json
js.html
<body>
<div></div>
</body>
<script>
function js_example() {
# This is where the function from Python is called
var json_obj = eel.json_example();
var tbl = $("<table/>").attr("id", "example_table");
$("div").append(tbl);
for(var i=0; i<json_obj.length; i++){
var tr="<tr>";
var td="<td>"+obj[i]["key"]+"</td></tr>";
$('#example_table').append(tr+td);
}
}
I tested both of these functions out separately with a few changes and they both work. However, here's where the problem starts. For some reason, the Javascript part is not getting anything from the function it calls from the Python code. the variable "json_obj" should be equal to the json I made in the Python function, but for some reason the return value of the function isn't creating tangible data that can be manipulated in the Javascript, basically returning nothing. And the eel transfer itself works as well. If you replace "return" with "print", it will print the json in the console.
Also, please don't tell me to just put the json itself in the Javascript. I have a reason for needing the json to come from the Python side.
So basically, here's my question: how do you get a Python function to create a value that can be manipulated in Javascript?
The problem is that when eel exposes a function what it actually does is it creates a new function that will return a promise containing the return value of your python function.
So you should have something like this instead:
let json_obj = '';
eel.json_example()(x => json_obj = x);
If you need more help on callbacks, refer to https://github.com/ChrisKnott/Eel.
Convert to json within Python if you're calling Python to begin with and send json to JS in the return value.
See: https://github.com/ChrisKnott/Eel/tree/master/examples/03%20-%20sync_callbacks
To do a synchronous operation that will take time to complete in Python and then return a value into JS, use;
let n = await eel.py_random()();
which is really
let mySlowReturnValueFromPython = await eel.myExposedPythonFunction()();
In fact I tried to code in my own promises and I was getting back garbage that looked like eel promises. The browser maintains a thread while you call this way, so the user can kick off a long Python operation and still interact with the GUI.
I'd note that you can still call things that update the GUI asynchronously. If you have a bunch of Python functions which return ready-made HTML as I do, then you can kick them all off in a row without waiting and they will update the divs whenever they return. I use this;
eel.expose(updateDiv);
function updateDiv(newData, divToUpdate)
{
var fieldToUpdate = document.getElementById(divToUpdate)
fieldToUpdate.innerHTML = newData
}
Then I call my Python function which gets the data synchronously, packs it up into a ready-made HTML chunk for the GUI, and then calls updateDiv from Python. I'm actually really enjoying the power that this "ping pong" interaction between a synchronous codebase and an asynchronous one give me when working with a GUI. Worlds better than arfing about with TK.
I hope this helps you and you can struggle less with it than I did. Once you understand how this works, Eel is really great. It apparently handles sync for you, just hand it a blank callback (or whatever black magic that is). What a great lib! Eel is just perfect for locally hosted GUI's. I'd like to see a better GUI framework than HTML/CSS/JS - the truth is that there really isn't one, those things are so well tested and stable, with so many available examples for whatever you could want to create.
I'd really like to see this become the native Python GUI solution. Browsers are extremely cross-platform and the only problem to solve when porting becomes interfacing the browser to Python.

using jint to call javascript using d3 from c#

I am currently working on a project where we need to generate some SVG based on some input data. Currently all this SVG generation is implemented in javascript using the d3 library. Note that my goal is to be able to reuse this logic and not implement it all over.
My problem is that I would like to be able to call this javascript from C#.
I have tried using PhantomJS and I am able to generate the SVG but I am not satisfied because
Each time I want to call the javascript it starts a new process and I
have noticed that it uses a lot of memory (In my case I saw 100 mb
which is too much in my case)
It seems a little unstable. I have
had some cases where the process just hangs
Development (On the javascript side) is pretty frustrating because it is hard to debug
Because I was not satisfied with PhantomJS I have also tried using jint and this seems really nice to work with. Unfortunately I haven't quite managed to get a working example up and running. Currently I am using AngleSharp to supply the DOM so that D3 has a place to write its data. This gives me the following example:
static void TestJint()
{
//We require a custom configuration with JavaScript and CSS
var config = Configuration.Default.WithJavaScript().WithCss();
//Let's create a new parser using this configuration
var parser = new HtmlParser(config);
//This is our sample source, we will do some DOM manipulation
var source = "<!doctype html> <html><head></head> <body> </body></html>";
var document = parser.Parse(source);
var jintEngine = new Engine();
jintEngine.SetValue("document", document.Implementation);
jintEngine = jintEngine.Execute(File.ReadAllText("d3.min.js"));
jintEngine = jintEngine.Execute("function testFunc() { d3.select(\"body\").append(\"span\").text(\"Hello, world!\"); return 42;}");
var res = jintEngine.Invoke("testFunc").ToObject();
}
The problem is that the line var res = jintEngine.Invoke("testFunc").ToObject(); throws an exception.
Exception screenshot
If I try replacing the line
jintEngine = jintEngine.Execute("function testFunc() { d3.select(\"body\").append(\"span\").text(\"Hello, world!\"); return 42;}");
with
jintEngine = jintEngine.Execute("function testFunc() { d3.select(\"body\"); return 42;}");
then the function is able to run without any exceptions. By playing a little with the logic I have concluded that it is the .append(\"span\") that causes the exception.
I am a little stuck so I was hoping that someone might have an idea that could point me in the right direction.
I have figured out the problems.
1) The document returned by parser.Parse(source); does not implement the function createElementNS which d3 uses. I solved this by using a wrapper that delegates the call.
2) d3 uses the variable ownerDocument which I havn't set. So I also had to add the following
jintEngine.SetValue("ownerDocument", new MyDocumentWrapper(document));
Note that this doesn't make the entire d3 library work. I have also noticed some problems with d3.geopath() but with these fixes I am able to execute my initial example.

JSP Parsing url and matching key words

Here is my question, I am using jsp script, trying to match a key word in requesting url and do something:
<script>
$url = '${pageContext.request.requestURL}';
if("${fn:contains(url, 'key')}" == true){
...
}
....
But this doest work... I am not sure where the problem is but I want it to be like when url contains this string, go in to the if condition.
Thank you
You are mixing JSP/EL and JavaScript as if they run in sync. This is wrong. JSP/EL runs in webserver and produces HTML code which get executed in webbrowser. JavaScript (JS) is part of the generated HTML code and runs in webbrowser only.
You need to do it either fully in JSP/EL, or fully in JavaScript. You can use JSP/EL to dynamically generate JS code which get later executed when the page arrives at browser. Rightclick page in browser, do View Source to see what JSP/EL has generated. You should not see any line of JSP/EL. You should only see HTML/JS code. It's exactly that JS code which get executed then.
You're using a JSP EL function to test a JS variable which isn't in the variable scope at that moment at all. This is not going to work. It can only test JSP/EL variables.
Here's how you could do it in pure JS:
<script>
var url = window.location.href;
if (url.indexOf('key') > -1) {
// ...
}
</script>
If you really insist in doing it using JSP/EL, you could do as follows:
<script>
var url = '${pageContext.request.requestURI}';
if (${fn:contains(pageContext.request.requestURI, 'key')}) {
// ...
}
</script>
This will then generate the following JS code (rightclick page in browser and View Source to see it):
<script>
var url = '/some/uri';
if (true) {
// ...
}
</script>
But this makes no sense. Whatever functional requirement you need to solve, you need to think twice about the right approach. Feel free to ask a new question about solving the concrete functional requirement the proper way.
If you want a parameter that the page was requested with, use ${param.paramName}. So in this case ${param.key}. See implicit objects in the docs. And if you just want to check it has a value try ${not empty param.key}.

Javascript functions

We are attempting to only make available certain functions to be run based on what request address is.
I was wondering how we could do this:
if(condition1)
{
$(document).ready(function() {
...
...
// condition1's function
});
}
else if(condition2)
{
$(document).ready(function() {
...
...
// condition2's function
});
else if...
I was wondering what a good pattern would work for this? since we have all of our functions in one file.
It depends on what your conditions are like...
If they're all of a similar format you could do something like
array = [
["page1", page1func],
["page2", page2func],
...
]
for(i=0; i<array.length; ++i)
{
item = array[i];
if(pageName == item[0]) $(document).ready(item[1]);
}
I like Nick's answer the best, but I might take a hash table approach, assuming the 'request address' is a known fixed value:
var request_addresses = {
'request_address_1': requestAddress1Func,
'request_address_2': requestAddress2Func
};
$(document).ready(request_addresses[the_request_address]);
Of course, request_addresses could look like this as well:
var request_addresses = {
'request_address_1': function () {
/* $(document).ready() tasks for request_address_1 */
},
'request_address_2': function () {
/* $(document).ready() tasks for request_address_2 */
}
};
I don't see any problem with that. But this might be better:
$(document).ready(function() {
if (condition1)
// condition1's function
else if (condition2)
// condition2's function
...
});
It would probably be cleaner to do the site URL checking on the server (if you can?) and include different .js files depending on the condition, e.g.
** Using ASP.NET MVC
<html>
<head>
<%
if(Request.Url.Host == "domain.com")
{ %><script type="text/javascript" src="/somejsfile1.js"></script><% }
else
{ %><script type="text/javascript" src="/somejsfile2.js"></script><% }
%>
</head>
</html>
This way, each js file would be stand-alone, and also your HTML wouldn't include lines of JS it doesn't need (i.e. code meant for "other" sites)
Maybe you could give more detail as to what exactly you are doing, but from what I can tell why wouldn't you just make a different JS file containing the necessary functions for each page instead of trying to dump all of them into one file.
I would just leave all of the functions in one file if that's the way they already are. That will save you time in rework, and save the user time with reduced latency costs and browser caching. Just don't let that file get too large. Debugging and modifying will become horrendous.
If you keep them all in one file, Add a script onn each page that calls the one(s) you want.
function funcForPage1() {...}
function funcForPage2() {...}
Then, on page1
$(funcForPage1);
etc.
Instead of doing what you're planning, consider grouping the functions in some logical manner and namespace the groups.
You'd have an object that holds objects that holds functions and call like this:
serial = myApp.common.getSerialNumber(year,month);
model = myApp.common.getModelNumber(year);
or
myApp.effects.blinkText(textId);
If you wanted to hide a function or functions per page, I suppose you could null them out by function or group after the load. But hopefully having things organized would satisfy your desire to clean up the global namespace.
I can't think of a particularly elegant way to achieve this using only JavaScript. If that's all that's available to you, then I'd at least recommend you use a switch statement or (preferably) a hash table implementation to reference your functions.
If I had to do something like this, given my development environment is fully under my control, I'd break up the JavaScript into individual files and then, having determined the request, I would use server side code to build a custom bundled JavaScript file and serve that. You can create cache copies of these files on the server and send client side caching headers too.
This article, which covers this technique as part of a series may be of interest to you.

Categories