Clear Blockly workspace without moving items to trash - javascript

I would like to use code to clear a Blockly workspace, and in some cases overwrite with new Blockly XML. The issue I am facing, however, is that Workspace.clear() moves current items to trash, which can be annoying when trying to reset a workspace, or overwrite it with blocks (which means clearing it first, as otherwise the current blocks would be overwritten). I have found that I am able to clear the trashcan with workspace.trashcan.contents = [], but this results in some unexpected behaviour regarding the rendering of the lid, which appears slightly ajar despite it being empty.
Even if I could find a way to clear the trashcan, this would still result in clearing all previous items in there, while all I'm looking for is to do a single clear action without impacting the trashcan. I've tried looking at docs for Workspace.Clear, but they don't seem to give any semantic way to do this. I've also tried looping through Workspace.getTopBlocks() with Events.Delete, but that also results in moving items to the trashcan.
I've also tried to implement a manual solution, something along the lines of:
const contentsBeforeClearing = workspace.trashcan.contents_;
workspace.clear();
workspace.trashcan.contents_ = contentsBeforeClearing;
For the first line, I've also tried Object.assign([], workspace.trashcan.contents_) and workspace.trashcan.contents_.slice(), but in all three cases (including the top one), the end result is equivalent to simply calling workspace.clear. I'm guessing this is something to do with getter-setters manipulating contentsBeforeClearing (as the variable's value has changed if you test it in the console after the clearing to have the deleted block(s)), but how to get around that is beyond me.
How can I clear the workspace without manipulating (not just resetting) trashcan contents?

Related

Update HTML text content in a while loop

I'm having a problem that seems very simple, but still I don't know how to solve it.
So, I have this tag in my HTML file:
<p id="best-individual-text" style="display: inline-block"></p>
For context, I'm building a simple genetic algorithm to evolve a population of individuals (strings) in order to reach a target phrase. In my .js file, I have a loop that creates the new population and finds the best individual of that population, and the loop only stops when one of the individuals is identical to the target phrase.
What I want to do is to update the best-individual-text text content with the string of the best individual in each generation. Since the while loop creates a new population in each iteration, there's going to be a new best individual at every iteration.
Inside this while loop, I have the following line of code:
document.getElementById("best-individual-text").textContent = getBestIndividual();
Note: getBestIndividual() returns a string
And here lies my problem: the HTML doesn't get updated. The tag remains blank until the loop stops, and only after that the tag is filled with the last best individual.
It works fine if I try this manually, that is, outside of the while loop. My only guess is that the while loop runs too fast for the HTML to be updated. Still, I think I've seen people update the HTML in a while loop, so I really don't understand the reason it is now working.
Also, I've tried making a setInterval instead of a while loop, but it still doesn't work. Even if it did work, it is not of my interest to have any sort of interval for each loop.
What could the problem be, and how can it be fixed?
Thank you in advance!
Here's the github in case anyone needs to see more of the code: https://github.com/pedroheck/genetic-algorithms/tree/main/Word%20Race
I tried out your code, and in the cases I hit where you enter some text, click "Submit", and nothing happens, what is actually happening is that your algorithm is in some sort of infinite, or long-running loop, and it never hits the point where you try to modify the HTML.
You can tell this by simply setting a breakpoint at the line that tries to modify the HTML, and notice that it simply doesn't get hit. Another clue is that the window becomes unresponsive.
My recommendation would be to look closer at your algorithm and try to set some limits. console.log statements will be your friend, because they'll help you see what parts of the code are running the most.

ReactJs : useReducer on array of object. I need more understanding

Still new to the world of Js and React, I just made a website that works. But it bothers me the way I made it work. And I would like a bit of insight into how I could do things the better way.
So here I made a simple project on the sandbox to reproduce what I did and ask a few questions.
Here is the sandbox: https://codesandbox.io/s/amazing-dream-oz8ec?file=/src/App.js
You will find a console.log(tab) to keep track of the evolution of the tab.
So here is a quick explanation of the project, I have two components (Mario and Luigi) that I want to interact with and react (no puns intended) with modification on one another. For this, I made an array of objects and put the characteristics of said components in each object. I then make changes to the array of objects with cases that I built in my reducer. From another point of view, I have Mario and Luigi, I want to be able to click on one of them to make them able to jump (by creating a 'jump' buttons that I want exclusive in term of visibility to one of them), then click on the 'jump' button to make one of them jump (which make the one jumping appear full screen on the webpage and the other one invisible for the time being). And the last thing I want an 'exit' button (that appears on while jumping) which will reset my value (of the array) to the original ones.
So here is where I get kind of lost.
First question: So I kind of get the difference between mutating an existing state (no re-render) and returning a new one (actually getting a re-render). In my first case 'toggleCanJump'
the mutation (tab.map(hero => (hero.canJump = false));) is affecting the return since it makes my tab's canJump value exclusive (only one of them can be true at a time), whereas in my second case 'toggleJumped' the mutation (tab.map(hero => (hero.canJump = false));) is not affecting the array, hence why in the className of the button I have two conditions to establish the classes (className={hero.canJump && !hero.jumped ? "btn flex" : "btn"})?
To verify that just comment on the mutation before they return in the first case 'toogleCanJump' and you will see that it is not exclusive anymore both 'canJump' can have the value true. Whereas even with the mutation, I can't achieve to have the value of 'canJump' reacting to triggering 'jumped' even with the mutation that is working as stated just before.
Second question: Which is kind of redundant with the first one. Since I don't seem to get full control of my array of objects, when one the components is full screen and the other one displayed as none (for example: when Mario is jumping and so Luigi disappear). I need a 'reset' button to actually toggle a case that returns (literally copy and paste) the initial value of my
an array of object. I find it clumsy but since I don't fully grasp the manipulation of my array (as stated in question one) I found this solution to make it work. So how would I be able to slice and re-insert properly my object in the array ?
This question is kind of the same as the first one but on a different scenario. I feel like I get the differences between mutating and returning my state (array of object), but I don't seem to be able to make it effective. Mutation on 'toggleCanJump' seem to work but on 'toggleJumped' actually does not, and is returning the tab as I declared it really the best way (more elegant one) to reset it ?
I would like to add that may be it is my logic that is not the good one ! Maybe it should be an array of arrays, I find object to be more talkative for future updates of the website. but I am not against doing it with an other manner.
If you feel like having a solution, or an alternative way of doing things. Your time would be much appreciated. Thank you for reading.
See reconfigured sandbox:
https://codesandbox.io/s/cold-frost-x62x3?file=/src/App.js
In regard to the first question, you are actually using map as though it is forEach and directly mutating state. Map is intended to return a new array, where as you are equating values to the original array by using "=".
The fact that only one appears to effect the outcome however, is an illusion (they both do) and caused by a different reason. Your dispatches were being set off multiple times -- some odd, some even: counter balancing the effect. This was happening for 2 reasons: 1. your reducer wasn't placed outside your function, and 2. your buttons were nested and therefor required e.stopPropagation().
In regard to question two, because your hero.style property is unique, you would need to create an object map to restore it. Its easier to keep it as since the characters are already hard coded into the initial state.

jQuery create a callback thats not a callback?

Alright lets see if I can describe this.
I have a handful of functionality that was created sometime ago, and works swimmingly. However there is a new desired spec, so without having to rewrite the code base in a matter of speaking, and without having to double up on code to pull the same effect off I am trying to figure out how I can go about making something jump back higher in the code within the same function to repeat the run of the function rather then doing the same code again below.
What I have is a click based triggers ie:
$('.selector').click(function(){});
In this function is about 30 lines of functionality to create a new element and populate it accordingly. However unfortunately in that same bit of functionality there is conditions to wether it should or not.*The previous requirement was when the element it creates is open and populated just throw an alert() saying essentially wrap up what your doing, and then go on to the next. *Now the new requirement is just close that and open a new element. Which I've gotten to close out the existing, and do everything I want it to do, except the population of the new element which is above where the condition is currently. Knowing there is no "go to" type of logic in javascript (or last I knew). the only thing I can think of is taking the same code from above and putting it in the condition as well, doubling up on the code and having litterally 2 copies of the same bit. I want to avoid that, but cant think of a way to do it. So here I am looking for ideas
Knowing there is no "go to" type of logic in javascript (or last I
knew). the only thing I can think of is taking the same code from
above and putting it in the condition as well, doubling up on the code
and having litterally 2 copies of the same bit. I want to avoid that,
but cant think of a way to do it. So here I am looking for ideas
Why don't you just pull this piece of code out into a function? You can run the function if the conditional is true in the original instance, and run it all the time in your callback? This is fairly minimal refactoring, just move the code out of the logic into a separate function, keeping it as is and maybe making some of the referenced variables into parameters.
So something like this if you want to run all the actions regardless of the conditional statements:
...
if(condition){
actionA();
}
if(condition2){
actionB();
}
...
$('.selector').click(function(){
actionA();
actionB();
});
You're familiar with that pattern, right?
var aCallback = function(){........};
$('.selector').click(aCallback);

MooTools: getChildren() on an invisble select returns an empty array in Chrome

I have some code that tries to grab the children options of a select: $('mySelect').getChildren().
Sometimes the select is visible and sometimes it's not, and this doesn't seem to make a difference in Firefox, .getChildren() returns an array with the select options. However, I've noticed in Chrome the exact same call will return an empty array if the select is not visible.
Once the select has become visible .getChildren() will return the select options even if it goes invisible again.
Is there a way around this initial empty array in Chrome?
Thanks.
Edit:
My actual code for this is part of a rather large application but I tried to build a jsfiddle for with enough information for this problem, http://jsfiddle.net/6Szua/3/ , but had no luck actually reproducing the error. It would be like instead of returning 0 and an array of objects it would return -1 and [ ]. In our code, -1 falls into a special case, so the behavior was different across browsers.
If I run the debugger in Chrome's developer tools I'm able to trace the select's options being built, but once the calls finishes, it's like they were never there.
Luckily, I was able to come up with a work around for this situation, but if someone else has run across something like this before, I'd still be interested in hearing about it.

javascript function "createCallback" called >50 times when I use addClass/removeClass in Firefox

I'm working on a web app in ASP.NET 2.0 that involves several GridView elements. When users click one of the rows in a grid, that row needs to show its selection by changing color. Each row has attributes set to identify its record type and unique ID:
<tr data-elementType='myType' data-myID='12' onclick='selectionFunction();'></tr>
I accomplish the selection through a javascript onclick handler on each row that calls a function that:
Removes the selected class from the previously selected row
Adds the selected class to the new selected row
Updates the value of a hidden field with the new selected unique ID so server-side code can know which element to perform an action on when a button is clicked (view, delete, etc).
One of these grids now has just over 700 records in it. In Firefox 3.6, the selection operation on this grid is horribly slow (about two seconds); in other browsers (even IE 7 and 8) it's not a problem. I put console.log statements at the start and end of the selection function, and in Firebug they show up very fast at the end of the delay, suggesting that it's not the selection function that is slowing things down. I used the profiler in Firebug and it says that "createCallback", which is defined in one of the "ScriptResource" script files generated by ASP.NET, is taking the huge majority of the time. What is createCallback and why does it seem to be so slow in Firefox 3.6? Is it a bug in FF, or is it a problem I can solve?
UPDATE: I am, of course, using jQuery to add/remove classes from the rows. I've been working with jQuery 1.5.2 and jQueryUI 1.8.11, but I updated to the latest (1.6.2 and 1.8.14 currently) to no avail. I tried putting a breakpoint in createCallback to see where it's getting called, and when it breaks there it's several frames down in the call stack from my call to removeClass. Here is what the stack looks like in Firebug:
createCallback() - in ScriptResource.axd?......
wherever possible trim: trim ? function(text=" ") - in jQuery
removeClass(value="selectedRow") - in jQuery
removeClass(classNames="selectedRow", speed=undefined, easing=undefined, callback=undefined) - in jQueryUI
selectionFunction() - in my .aspx page
onclick
I don't understand why jQuery is triggering an ASP.NET generated function like this.
UPDATE 2: some more investigation has provided some more detail. It seems that this "createCallback" function is getting called A LOT when I use addClass/removeClass, and it's happening in both Firefox 3.6 and Firefox 5. I found the same function in Chrome and put a breakpoint on it, and it's not getting called at all, so this seems to be a Firefox thing. I put a breakpoint on the function/line in question and selected a row, and the breakpoint got it 57 times. Only the first two involved me calling removeClass and addClass; the rest had createCallback several times in the callstack, and sometimes BeginRequestEventArgs too. I've noticed it getting called also when I mouseover other jQueryUI stuff on the page (tabs), when jQuery uses addClass and removeClass. But why is it getting called so many times when I do work on tr elements?
I'm changing the title and tags to reflect the real issue.
UPDATE 3: createCallback is getting called about the same number of times whenever I select a row in any of the grids, even if it only has 6 rows in it. But in that case it's not a performance problem, and the profiler shows it only taking about 30% of the execution time, while it's at least 80% when I profile selection on the larger table. So createCallback seems to perform worse when it's used in the context of more stuff visible on the page. But it still seems like jQuery shouldn't cause a call to createCallback, especially since I couldn't fine any references at all to it in Firebug's script search. And it appears to only get called in Firefox!
Note also that all of these grids are on the same page, but only one is visible at once, because I'm using jQueryUI tabs.
UPDATE 4: I managed to get something similar up on jsFiddle as requested. See here. In Firebug, find createCallback and set a breakpoint (just below my click handler in the script, where it begins with Function.__typeName = "Function"; Function.__class = true; Function.createCallback = function (b, a) and reload the page. I get a lot of calls to it.
I have very little knowledge of ASP however it sounds like your problem is purely client side.
Declaring on "onclick" event for each row is not the most sensible way to handle the rows being clicked. Especially when you get into the quantity of rows you're talking about (~700+).
A better way would be to add a click event handler to the table and figure out what is clicked when it happens. I have written an application where a similar size table is being handled and we're not seeing anything like the lag you're experiencing upon click. there may well be other factors causing your click events to slow down however I would still suggest something along the following lines is worth implementing in any case:
$(function(){
var rowSelectedClass = 'rowSelectedClass';
$('#myTableID').click(function(e){
if(e.target.nodeName === 'TD'){
var $tr = $(e.target).parent();
$('tr.' + rowSelectedClass).removeClass(rowSelectedClass);
$tr.addClass(rowSelectedClass);
// ....
// Do whatever else you want to do when the row is clicked
// ....
}
});
}
A good article to take a look at which advocates this method (and a few other handy jQuery tips) can be found here: http://www.artzstudio.com/2009/04/jquery-performance-rules/#leverage-event-delegation
Also worth noting that if your table has rows added dynamically after the page is loaded then consider using .live() instead of .click().
UPDATE # July 28th 2011 9AM
Having taken a look at the source more closely, I think the supposed calls to "createCallback" are a red herring. The line within your original jsFiddle source which contains the "createCallback" function is actually a really long string (~90,000 characters) of javascript. I think the fact that "createCallback" is the first function within that string is misleading Firebug's profiler. When you profile your original page's load, there are 2261 calls and as you said, there appear to be lots to "createCallback"
I've "beautified" (hate that phrase) this long JS string via http://jsbeautifier.org/ to make it readable and re-added it to a jsFiddle page. You can see it here: http://fiddle.jshell.net/KvpmE/1/show/. Now when you profile this page's load you'll see a similar number of calls (2267 - not sure what happened to the other 6!) but importantly not a single one to "createCallback".
I still can't offer any solution though because essentially I've been unable to re-create your original issue which was that there was a 2 second lag in Firefox 3.6 when clicking a row.
Is this still the problem you're having?
Could you try and see whether you can re-create the problem within the updated jsFiddle page?
Also try and add the de-minified JS to your page to see if it helps you track down the actual functions being called when the row is clicked and therefore where the lag is taking place.
Mr. Jefferson,
It really sounds to me like you're actually performing a postback without knowing it. Have you set a breakpoint on the server side yet to see if something is inadvertently firing your update panel? It really sounds like some kind of postback is happening that is requiring a reload of dependant scripts.
I say this because 1) the problem you're having makes absolutely no sense - you're 100% on the money with JQuery and the ASP.NET Client Framework not even knowing they're neighbors in this case, and 2) the BeginRequestEventArgs instantiation sounds like the PageRequestManager thinks it should be doing something in response to your triggers... You could also try breaking out Fiddler and just doing a quick sanity check to make sure some update panel of yours isn't firing. There should be no HTTP traffic during the ops you're describing.
Sorry if this is an absolutely useless post for you, but with all of the work you've gone through to troubleshoot the client side it can't hurt to set a server side breakpoint just to do a quick sanity check / occam's razor...
Good luck - happy coding.
B
Function.createCallback is used a lot internally by Ajax Toolkit and maybe its being called within your code unintentionally too http://msdn.microsoft.com/en-us/library/dd409287.aspx.
Since this is browser dependent, I would check code paths that are executed based on a specific browser.
Another clue to look for is if you're having any Ajaxtoolkit components for the grid or its individual rows as that would explain the increase in number of calls with the increase in rows.
There is also Type.createCallback function (http://msdn.microsoft.com/en-us/library/bb397568.aspx) so if you have any Type related code or methods, I would check those.

Categories