NEIL FRASER: So I wanted to talk about how you can
develop the core of Blockly.
This is one method that I saw, which
is print out what you want, modify it, laminate it.
And this is something that somebody found,
a co-worker found in a school in Malaysia
that didn't have computers.
I just thought that that was one of the highlights of Blockly,
that it showed up in this form.
But it does illustrate an interesting way
to make hacks to the core of Blockly
in an unconventional manner.
OK.
So we're all software engineers.
We know the development cycle.
You edit code.
You compile.
You see the result. You discover what's broken.
You go back.
You edit the code.
You compile.
And we've all seen classic xkcd.
However, if you're working with Blockly,
we're also JavaScript engineers.
And so we know that there's a better way than this.
If you're using JavaScript, and you're compiling,
you're doing it wrong.
That's my opinion.
And you may have other opinions, but that would simply
be incorrect.
Now, compiling actually is extremely
important for JavaScript for things like--
well, before you release, essentially.
You need to be able to minimize.
It helps find errors and so on.
However, in a development cycle, it really,
really helps if you can just edit, reload your browser,
edit, reload your browser, because the compile step,
while it does have some value, it just
slows everything way down.
Oh, yeah.
Here we are recompiling Blockly.
And it takes, I don't know, a minute, something like that.
It's not too bad, but we don't--
at Google, when we're developing Blockly,
we don't recompile it until we're ready for release
or getting close to it, or debugging
something similar to that.
So almost all of Blockly's development
happens in the playground.
I assume that most of you have seen the playground.
How many of you use it exclusively for developing
when you're in the core?
OK, so basically we found the Blockly team in here.
The playground is the way you develop Blockly.
It is completely uncompiled.
So if we look at the source, you'll
see that it pulls in each of the files
individually, which is slow.
I mean, if you're loading this over a network,
you do not want to do it this way.
But it means that you can modify--
[INAUDIBLE] you can modify your code, and then just hit Reload,
and it's there.
The playground also gives you every bell and whistle
you can imagine.
So we can pull out some blocks here.
10 times if-- that's good enough.
We can see what the xml looks like.
Although, based on this morning's discussion,
it looks like the xml is about to change a little bit.
We can export to JavaScript, Python, PHP, Lua, Dart.
We can verify that all the generators are working fine.
We can also export and then reimport to make sure
that it round trips.
There is also undo, works fine, redo.
And then we've got different modes.
So depending on what you're doing,
switching to a different toolbox may
result in other bugs becoming apparent.
So with this toolbox, if you drag over,
it deletes, whereas the other one's got categories.
So very, very different mode.
Scroll bars, you got zoom, in, out.
Basically, it gives you every bell and whistle
you can imagine.
You can also move the toolbars around to the top,
or we can go to take variables.
So we have logic blocks up here.
Every permutation of possibility is available here.
And then if you think that that's good,
try switching right to left, and make sure that everything
renders in this direction.
No compile necessary.
As long as you aren't modifying the goog.require
and goog.provides, you don't need
to recompile in the playground.
In addition to playing with blocks--
well, our basic set of blocks are fairly extensive in terms
of the things that they test.
For instance, this tests whether images work.
It's ironic that the string block
tests images, but whatever.
You've got mutators, dropdowns.
We've got disabled blocks.
So there's basically one of everything in here.
However, there are some blocks that
are so weird that we couldn't figure out
how to fit them in logically.
So there's also a set of test blocks.
Let me switch back to left or right, because it's not my--
test blocks.
AUDIENCE: [INAUDIBLE]
NEIL FRASER: Yes, it is.
It just has failed to--
oh, OK.
These are test blocks that really torture Blockly in a way
that you really shouldn't be doing,
like what does an empty block look like, can you
drag shadow blocks, as opposed to non-shadow blocks,
can you create something with two variables in it.
And this is a real torture test.
A broken image.
How does that render?
And emoji and zalgo text.
Is this a bug?
Yeah, I think zalgo text is the bug, not the--
yes, we did not imagine that--
I did not imagine that the text would be variable height,
but yes, this does exist.
Yes.
What's also useful about the playground is--
let me switch back to that--
the xml stays in this window even when you reload.
So if you've made some changes, and you reload the page,
you can import the blocks again.
You can build up your program and just keep iterating it,
reload, import, reload, import, without having
to build up your program again.
There are also some stress tests here.
Airstrike is-- we'll just dump 100 blocks onto the canvas.
That allows you to test for things
like responsiveness of dragging and finding connections.
The algorithms for that are quite fun.
And then the other-- oh.
Yep.
I love that effect.
And then we've also got the spaghetti test,
which loads a massive program.
It is enormous, but a key feature of the spaghetti test
is in the console.
When you open the console, it tells you how long
it took to render that.
So if you make a change to how Blockly renders
or imports or loads or anything like that,
you can check the spaghetti test to see if you've reduced
the time or increased the time.
So it's a good performance check.
And lastly, there's event logging.
This is really useful if you're trying to figure out
how the event model works.
Just turn on log events, open the console, and clear it.
I'll make it bigger.
So clicking on that category fires a UI event,
and we can drill into it and see that it's a category event.
The new value is logic.
The old value is nothing, whereas that one, the old value
was logic.
Now it's loops.
So you can watch the events that go
through when we create a block.
There is a create event.
The block got selected.
The block got moved.
And there are two move events here.
One of them is where I dropped it,
and then there was a snap to the grid, which
is the follow-up move.
All of these-- all these four events
are grouped, using the same group ID.
So that means that if I undo, it will delete the whole block, as
opposed to un-snap it and then undo again,
and it moves it to 0, 0, and then undo again,
and it deletes it.
So this is the best way to explore the event model.
And yeah.
Don't be recompiling Blockly over
and over and over again when you're modifying it.
Just use the playground.
That's how we developed Blockly.
AUDIENCE: [INAUDIBLE] about adding blocks?
NEIL FRASER: So yes.
The playground also gives you a good place
to manipulate Blockly in other ways.
So here's the code for the playground.
One of the things towards the top of the file
is a list of all the parameters for Blockly,
should comments be allowed, should you
allow disabling blocks, what does the grid look like,
and so on.
So these can be modified here.
These are fairly-- sometimes you actually
do want to turn off scroll bars, see how that works.
Many of these you can control within the UI, but not
all of them.
Max blocks.
That's a fun one.
That didn't turn out to be as useful
as I thought it would be.
And if you are testing out a block, you can plug it in here.
And I'll just modify the xml, wherever it is.
There it is, so that the block shows up in the tool box.
And that way you can test out your blocks in here as well.
If you're filing a bug, that is--
or if you've run into a problem with a block,
and you describe it on the newsgroup,
one way is to just give a code dump of here's my JSON,
here's my generator, and why doesn't it work.
An even better way to get a great response
is to insert your block into a copy of the playground
and host it somewhere, and then just point it at us.
And then we can actually look at it.
It'll be a lot easier to find out
what's going on, as opposed to trying to read code
and reverse engineering what's going on.
Any other questions?
I'm trying to go fairly quick because we're dragging.
Yep.
AUDIENCE: [INAUDIBLE] Thanks.
So I think you alluded to this.
Are these things you could turn on outside the playground,
like the event logging.
So if I've got my own Blockly workspace, this is just a flag?
NEIL FRASER: It's not exactly a flag.
AUDIENCE: It's an event listener that you set up
with the workspace.
And so it's available on a per block place
basis as an on change listener.
The on change listener of a block
will refer to any events coming from the workspace it's
attached to, but you can also have application level
hook into the workspace and get all the same events.
So in figuring out what events are available,
this is a great way.
NEIL FRASER: Here it is here.
It's workspace, add event listener, and a function.
And the function is console log e.
That's it.
So you can write that yourself.
It's not--
AUDIENCE: So this is how we implemented
the real-time system [INAUDIBLE]..
We hook into this, and then we propagate the events
between all the clients.
NEIL FRASER: [INAUDIBLE]
AUDIENCE: I can see the playground's
great for testing that your blocks work
the way you're expecting, and that they're generating code,
et cetera.
How would you test that that generated code is actually
producing a sensible result?
NEIL FRASER: For that, you need to copy the code out and paste
it into some interpreter.
But it's very easy to sanity check
to see whether you've got the right thing while you're
writing the generator.
You've seen the generator unit tests?
[INAUDIBLE] tests and generators.
Index.
AUDIENCE: [INAUDIBLE]
NEIL FRASER: Oh, yeah, that's right.
Yep.
AUDIENCE: [INAUDIBLE]
NEIL FRASER: Yes, or I think I can--
yeah.
Or I can use Firefox.
They don't care about security as much.
They've made different design decisions.
AUDIENCE: [INAUDIBLE]
NEIL FRASER: Right.
The generator tests have got a dropdown.
You can choose the category of blocks
that you want to test and then load them in.
These are unit tests written in Blockly.
Every block that we have in our sample library is tested,
lightly tested.
We don't try every edge case.
So here, we're testing the logic blocks, the equalities,
the greater than, the less than, the if blocks,
that sort of thing.
We can click on JavaScript, and this is the code
that it generates.
And we could just copy this.
And since it's JavaScript, we can run this in a browser.
AUDIENCE: [INAUDIBLE]
NEIL FRASER: Yep.
Just hit Enter, and number of unit tests run, 32.
OK.
It's all good.
If you wanted to try Python, again,
copy that, click on the interpreter link.
It will find some interpreter out there somewhere
in the world.
No idea who these people are.
Hit run, 32, and you can do that for every one.
These don't tend to catch a lot of errors,
but we have tests for them nonetheless.