WWDC2014 Session 512

Transcript

>> Hello, everyone.
I'm Tim Hatcher.
Good morning.
Thanks for coming.
[ Applause ]
So I'm going to talk to
you about Web Inspector
and Modern JavaScript.
But first, I'm going to just
talk about Modern JavaScript.
So, what exactly is
Modern JavaScript?
Well, let's go through some
of the history of JavaScript
which is also known
as ECMAScript
as some of you may know.
But it's had a long history.
It's been around since the '90s.
And it had a lot of
momentum back in the '90s
when it was first part
of the browser wars,
but it kind of sputtered
and stalled.
But JavaScript is alive
and well nowadays.
Everyone is using it from web
apps to server applications,
and some of the standards bodies
have been battling over some
of what should be included in
the next version of JavaScript.
And I'm happy to say that they
finally started coming together
and started releasing what
is known as ECMAScript 6.
And the sixth edition
brings a lot of cool things
and it's really just JavaScript
and that's how I'm
going to refer to it.
In this modern JavaScript world,
there's a lot of great things.
And this is just some of them.
There's some destructuring,
maps, promises.
And let's go over some
of these new features
that are also now available
in iOS 8 and OS X Yosemite.
So when they're available, I
mean, you can use them in Safari
or your iOS applications or
Mac applications and not just
in web views but also a
JavaScriptCore context.
So let's talk over
some of these.
Let's first talk about
some math additions.
JavaScript has had a math object
pretty much since day one.
But JavaScript nowadays is super
fast, with the modern LLVM JIT
that we have in iOS
8 and OS X Yosemite.
You need these super fast math
functions to do complex things
like WebGL or complex
scientific calculations.
And most of you will recognize
a lot of things in this list
that you've used in the past
for your own applications.
And they're now available
in Modern JavaScript.
So that's the math additions.
Now let's talk about
maps and sets.
So, what do I mean
by maps and sets?
Well, in JavaScript, you
might think of this as a map.
This is something that you
create as a generic object
and it's really just
a property bag.
You can throw whatever
you want on this object.
You can set simple strings and
any object can be the value.
And you can remove
things from that map.
Well, these maps have
some limitations.
There's string coercion when
you're-when it comes to the key.
Everything that is the key needs
to be coerced into a string,
so it's not going to give
you exactly what you want.
If you want to use it
for a property bag
that's tracking some node,
it won't work.
Well in Modern JavaScript,
there's now a map object.
And it does pretty
much the same thing
that you would do
with an object.
It has a little bit
different syntax and API,
but it's pretty much
all the same.
The most powerful
thing you can do
with the map object is you
can use any value as the key.
And a lot of people will
use this to track DOM nodes
that they have in the page,
adding some additional data
on the side instead of tacking
it onto the DOM node itself.
So it really allows you
to compartmentalize data
that you're tracking
on the page.
But there are some
issues with that.
If you add it to the
map, that map is going
to hold a hard reference to it
and that's why Modern
JavaScript has a WeakMap.
And that means whenever
the key disappears
or gets garbage collected,
it's also removed from the map.
So in this case, I have a
node in my WeakMap and when
that node is removed by doing
a remove call or a removeChild
in that page, it would
no longer be in the map
and the data that's associated
with it will also get
garbage collected.
So that's maps and sets.
And there's also a set
object that I didn't cover
but it's pretty straightforward.
It only allows the key
to be added to the set.
So now let's talk
about Destructuring.
If you got excited about some
of the new features in Swift,
this will be right up your
alley as far as JavaScript goes.
It allows you to return like
multiple objects in an array.
In this case, I have an
array of two numbers here.
And traditionally, I
would have to collect
that in a result object.
And I would have to break
each piece off from that array
to use it in a separate
variable that made more sense
in the scope I was using it in.
But with destructuring, we can
break that down into one line.
Now my function that's
returning two results
that maybe didn't
make sense as array,
but it was what I could use to
return multiple things at once,
I can now save those
into the alpha
and beta variables
right there in one line.
And this might look like an
array but when it's on-when it's
on the left side, we're dealing
with the destructuring syntax.
And it's not just for arrays.
You can destructure objects.
And this is when it becomes
more of a pattern matching.
So in my example here,
say I have a point object.
And normally, I would have
to save it off into a result
and break each piece
out if I wanted
to use some more concise
syntax for those variables.
But now, I have object
destructuring in this case.
And if I'd want a different
variable name than the property,
I can separate them by colons,
so x is the value that's coming
out of the object
pattern matching
and my x is the variable name
in the local scope in this case.
But if I want to
use the same name,
I could omit the second
piece and just use y.
And y is now a local
variable in this scope.
And you can do some
really fancy things
that I don't examples for.
But you can deeply nest these
pattern matches and objects
with arrays and vice versa.
So you can really
break apart your object
if that-if that's what
works for your application.
So that's destructuring.
Now let's talk about what
we call the Spread Operator.
And this is something that is
borrowed from many languages,
but it comes in very, very
handy and I love using it.
It's-It really takes away
some of the common idioms
that you would do before if
you're building up arguments
that you want to call in
a function as an array,
before you would have to
resort to .call or .apply
and pass in those arguments.
But now, with the Spread
Operator which is represented
by three dots prefixing
an object.
And in this case
it's-it's an array.
But secretly, the Spread
Operator works on anything.
It even works on maps.
And it will break it out
in key value sequences.
So, anything that's has support
for iteration, which I'll talk
about in a bit, can be spread.
And this will spread it out
and call my function foo
with the three arguments
that are in the array.
One thing that you could
never do in JavaScript
and you can only do now with
the Spread Operator is called a
constructor with an array
input or a map input.
You can now take your parts
of a date and spread them
across the date constructor
instead of having
to manually do 0, 1, 2 and
break it out like that.
The Spread Operator
is also useful
in the construction
of array literals.
Say you have something
that's pretty repetitious.
You want to have a separate
form and a combined form.
Normally you have to either
repeat the data or push and pop
and add everything,
concatenate everything together.
But with the Spread Operator
you can just spread those other
arrays right out into the new
array that you're constructing.
So this is a handy way to do
pretty complex concatenation.
And you can understand
what it's doing
without having the
parse different calls
to different array functions.
So that's the Spread Operator.
Now let's talk about
something new.
A new For loop that's
available in JavaScript.
JavaScript has traditional
loops, which you can iterate
over an array by doing
an index and a length.
And you still might need
to use this if you care
about the index or the length.
And you're doing some complex
operation based on those.
Some people have avoided this
syntax because it's ugly.
And they use something
for-called forEach on an array
that lets you iterate
over individual items
and you handily get
the item right there
that you can work with.
But this creates a closure.
It does a lot of complex
things that you might not want
to deal with overhead-wise.
Well, with the new For loop
that's in modern JavaScript,
this is all you have to write
to iterate over an array.
And this will iterate over
every item in the array
if you break early,
it will stop.
But it starts at the first item.
But it's not just for arrays.
Say you have a set, you
can iterate over that set.
And if you have a map you can
iterate over the key and value.
Very similar to what
you can do in Swift.
So now you have the key in value
right there to process both
at the same time instead
of doing extra lines
of code using the for-in loop
which is available
on JavaScript.
Now you can do it
right here with for-of.
And for-of is the
only way to iterate
over the keys in values in maps.
For-in will not do
what you expect
and that-for reasons I'm
not going to go into.
But maybe you want to
iterate over a WeakMap.
That's not supported.
For reasons that involve
the garbage collection,
you cannot iterate over the
keys and values of the WeakMap
and this is part of the spec.
So, that's for-of loops.
Now, one of the new
things in modern JavaScript
that I'm really excited
about is Promises.
And it solves a longstanding
problem of JavaScript.
Now that JavaScript
is moving more
and more asynchronous everything
is asynchronous, you don't want
to be blocking your application.
And say you have a function that
you've written that loads a URL,
maybe it does an XHR behind
the scenes for you to wrap
up all the different
browser incompatibilities
that are out there.
So this will load a URL
and that's all it'll do.
You can't get the data.
To get the data, you might be
inclined to do a return result
that gives you the
data that was loaded.
But this is synchronous.
You can't get away with
this in a shipping product
without blocking
your user interface.
So, you have to resort
to a callback function.
And JavaScript makes
this real easy.
I do this everyday
in JavaScript:
pass in a callback function.
And it works and it's very
usable and it's very handy.
But when it gets deeply
nested and you're passing
in multiple information
and it just gets confusing
and hard to follow.
You have all these load
calls in this case.
Which one is handling
which information?
Well, this is what
Promises solved.
With Promises you can
write something like this
where the first load
returns a promise.
And immediately on
returning that promise,
I can call the .then function.
And that's pretty much
the only API you need
to be concerned about
with Promises.
And you can pass a call
back to that .then function
which will get called when
that promise is fulfilled.
And that callback can
return another promise.
And this where it's magical,
you can chain-keep
chaining along that.
So these callbacks are in line
here just for clarity for you.
But they might be
named functions
that you have somewhere else.
And it makes it very clear that
this is the order of operations.
So that's Promises.
And taking it to the next level
you can then use another API,
a global API, Promise.all.
And what this does is you can
pass in an array of promises.
And it will return a new
promise and that new promise
that it returns is dependent on
all of those promises finishing.
If any of them error out,
your "then" object can
get past the callback
that gets called for errors.
But in this case, "done"
will get called when only all
of those promises
succeed or fulfilled.
But maybe you only care
about the first one.
You're loading a bunch of images
and once you got one
image you're ready to go.
That's where Promise.race
comes in.
It will call your
callback when the first one
of those promises is fulfilled.
So that's a quick
glance of Promises.
So that pretty much wraps it
up with Modern JavaScript,
at least the parts that
we've already implemented
and decided were
ready for consumption.
There's a lot that's being done
in ECMAScript 6 that
is not ready.
And it's going to be
coming down the pipeline.
But these pieces we feel
that you're ready to use
in your application, in
browsers that support them.
So now let's talk about
the Web Inspector.
So if you're not familiar
with the Web Inspector,
this is what it looks like.
And we've had this UI for a
while but we've done a lot.
We've fixed a lot of bugs.
We've added a lot of features.
But the main thing we've done
this year is make the Web
Inspector available
in more places.
We've listened to your
feedback and you want to be able
to inspect your Mac application.
You want to be able to inspect
your JavaScriptCore context.
And that's exactly what you can
do with iOS 8 and OS X Yosemite.
So with Safari, you've been
able to inspect your iOS apps
and iOS Safari by tethering
up to your computer.
But now you can inspect your
Mac application and right there
from Safari see a list
of your Mac applications.
So what's that look like?
But first, like I said, you want
to inspect your JavaScriptCore
context.
But Web Inspector is
all about the web.
And it's only been able to work
with WebKit up until this point.
But now Web Inspector
can connect
to your JavaScriptCore-based
applications.
So even if you're
not using a web view
but you're using JavaScriptCore
for some logic in your game,
you can now debug
that JavaScript right
in the Web Inspector
and it's really great.
So let's-let's show
you what it looks like.
So, Mac App inspection, like I
said, will show up right next
to your iOS devices
in the Develop menu.
In this case, I have two Mac
Apps and the second one here,
JSPong, is a JavaScriptCore app.
The first one is a web view
but they're right
there side by side.
They're first class citizens.
And like I said, you
can also still connect
to your iOS applications
and iOS Safari
from the same Develop menu.
But for Mac App inspection
we require you
to add an entitlement
to your app.
You don't want anyone else
debugging your JavaScript
context or stealing
your JavaScript code
from your Mac Application
that you've worked so hard on.
So we require you to have this
entitlement on your applications
that you're developing locally.
And it's very simple to do
and I'll give you a demo
of it here in a little bit.
But what about JavaScriptCore
inspection?
What's that look like?
Well, it looks just
like the Web Inspector.
This is the same Web Inspector
that you saw a little bit ago.
The other one was
for the web view.
This one is for JavaScriptCore
context.
There's a couple of buttons that
are missing that don't apply
to JavaScriptCore context like,
styles and the DOM
and things like that.
But for the most part
it's everything you need
to debug your JavaScriptCore
application.
And you have the full console.
You can do a REPL, evaluate
JavaScript or see console.logs.
Console.log is now available in
your JavaScriptCore application.
So if you have your own log
function you can now abandon it
and start using console.log
and get all the great benefits
of the Web Inspector's
Log functions.
But if you don't do anything,
the console is pretty much
all you have available.
And I'll tell you why.
We don't know what
you're evaluating
in your JavaScriptCore context.
If you're evaluating
large scripts,
those are something you
probably want to debug
but you could be evaluating
something every 200 milliseconds
and that would quickly
pollute the sidebar here.
So you-any script
that you want to debug
in the Web Inspector we will
need you to supply a URL
or just a plain name
for that script.
And we've given you a
couple new APIs for this.
There has always been the
EvaluateScript functions.
We now have a new Objective-C
one that takes a sourceURL,
and this URL can be a file URL.
It can be any URL.
The Web Inspector really
doesn't take it other
than to get the name
at this point.
But if it's a file URL, it will
have a little bit extra benefit
and I'll talk to you
about that a little bit,
but JSEvaluateScript has
always supported the sourceURL
but a lot of people
just pass null to it.
So if you're using
the old C API,
make sure to start passing
a sourceURL for things
that you want to debug
that way they will show
up in the Web Inspector.
And that's for scripts.
But what about your context?
Identifying a context is pretty
difficult with JavaScript.
We don't know what it is.
By default it will just say
JSContext in the Develop menu.
But if you have a multiple
context, you don't want
to see a list that says
JSContext, JSContext, JSContext,
you want to identify those.
And as the developer, you
should know what you're using
that context for and
we provide this new API
that allows you to
name your context.
And the name is only
used for debugging.
It will only show up in
Safari's Develop menu.
So let's just give
a demo of this.
So I have a sample application
that we released a while ago
at a previous WWDC: JSPong.
And it's a simple pong game.
But I have some things I need
to do to it to make it work
with JSContext inspection.
The first thing I need to do
is make sure the entitlement
is there.
And if you're in the Apps Store,
you probably already have
an entitlements file.
In this case, I already
have an App Sandbox
and that will give
me an entitlement.
And I have it right here in the
sidebar, JSPong.entitlements.
So let's go in and add the
entitlement that we need.
And I said it was
com.apple.security.
get-task-allow, and
it's a Boolean.
And we'll go ahead
and say "Yes."
So that's all I need to do
to allow JSContext
inspection in my application.
And I'll go ahead and save that.
And I'll go ahead
and build and run it.
And it's a very simple
pong game.
The AI is controlled
by a JavaScript
that you can modify
here in the app.
I'm not going to
talk about that.
But now I can go to Safari
and, in the Develop menu,
I will see Mac Pro and I will
see JSPong and my JSContext.
And I didn't name
the context yet,
so it's getting the
default name.
And I'll go ahead
and inspect that.
And you'll see the
resources are empty.
I'm not seeing that that
AI script that I've loaded.
But I-if I want to debug that,
I'll need to give that a name.
But at this point, I have
access to the console.
If you don't do anything,
you can do evaluations
here in the console.
You can get access
to any globals
that you might have
available in your context.
And you will see exceptions
in logs and errors.
And in this case, we
have an example exception
and this will give
you a back trace,
not just of your JavaScript,
but of your native code.
So you can see exactly
where that function
or script was evaluated all
the way to your native codes
so you can trace it back
to the exist-the origin.
So let's go back into Xcode
and name some of these.
So it's pretty simple.
I'll just comment this out.
This will name my
context, Pong Context.
I only have one context.
But if I had multiple ones,
it would be imperative
for me to name them.
And when I'm evaluating
the AI script,
all I have to do
is construct a URL.
In this case, I'm just
making a URL with a string
and it really doesn't
have a location.
And I'll just use the
new withSourceURL method
and pass in that URL.
Now let's build and run
and see what happens
in the Web Inspector.
We'll go ahead and
reconnect to the pong game.
In the Resource sidebar,
we now have that AI script.
And in the app, we didn't
syntax highlight it.
But Web Inspector
knows exactly how
to syntax highlight JavaScript.
So we can set breakpoints
right here.
And since the script is called
every iteration of the movement,
it should break right away.
And now I'm in the debugger.
I have access to the call stack.
There's nothing other than
this function being called.
But if there was a
deeply nested call stack,
you would see it right
there in the sidebar.
And I can also bring open the
scope chain and we can-just
like you would any
JavaScript context,
you can now inspect the objects
that you're getting passed
around or your global
scope in this case.
And we can do what any
debugger does and step through,
and do anything you would
do in a normal debugger,
in addition to hovering
over variables
to see their current
value or evaluate things
in this current scope
in the console.
So in this case, let's try
modifying the ball here.
Maybe we want to modify
the rules of pong here
and make something
really easy to hit.
So I've gone ahead
and modified that.
And I have an update function
here that will redraw my scene.
And you can see the
ball increase in size
as I may-after I
made that change.
And this is working with
Objective-C bridged objects.
The ball object here is a
bridged Objective-C object
that you can use as you would
a normal JavaScript object.
So that's JSContext inspection.
And we'll go ahead and play it
and the ball stays the same
size and keeps on going.
So again, any web view, any
JavaScript context that you have
in your application can
be debugged now as long
as you have the right
entitlement.
And this also applies for iOS.
So only builds that you build
and run on to your device
or into the iOS simulator
will be inspectable.
Any app from the App
Store will not be allowed
to be inspected by anyone else.
So that's all you need.
And again, name your context
and name your scripts,
so you can easily identify
them when you're debugging.
So now let's talk about
something that we've had
in the Web Inspector for
a while: the Timeline.
And something new this year
is the Source Code Timelines.
So what do I mean by that?
What sorts of problems
does it solve?
So Source Code Timelines help
you answer this question.
What happened when I click
on something on the page?
Maybe it's a new project
that you're working on,
maybe it's something
you wrote years ago
and you don't remember how it
worked and you want to find
that line of code that handles
this click, so you can fix a bug
or so you can just modify
it for some new behavior
that your client is
asking you to add.
So, when this click happens,
there's a lot of stuff
that probably going on.
But you really only care
about code that you wrote,
maybe you have some analytics
code or a lot of other code
that it might be
hard to decipher
or see interleaved functions
and event calls and all of these
that happen in a big
modern web application.
So when I click on that,
you start wondering, "OK,
what script is handling
this button?"
And it turns out it's this one.
But with the new Web
Inspector, we can dig deeper.
In the script, I can now see
a timeline representation
of what the script was doing.
So I can see over time where
the mouse events are coming in,
where the clicks events,
where the timer was added,
where the timers are firing,
where I might be
doing forced layout,
which is a pretty evil thing
to do in a modern web app.
So what's it looked like
in the Web Inspector?
Well, here's the new
Web Inspector Timeline.
And you can see in the sidebar
here we have all of our scripts
and resources from the page
broken out in their hierarchy
of how they're included by
you, the developer, in the page
and you can expand
each script to see what
that script was doing and
where the line of code was.
And in this case, you'll
see a whole timeline
where things are
happening repeatedly.
You'll start seeing
patterns and allow you
to identify problem areas if
something is firing too much,
too little, not at all, if
you don't see it in the list.
And if you want to dig deeper
into the code, all you have
to do is click right
there on the sidebar
and it will take you right to
that location, and you can mouse
up and down through the sidebar
and have your code on one side
and your timeline
data in the sidebar.
So you can get a good overview
of what the script is
doing really quick.
So that's the Source
Code Timelines
and I'll give you a demo
here in a little minute.
So something else that's new
in the Web Inspector
is Breakpoint Probes.
So you might have some
information that you want
to know when that
mouse is clicked
or when your mouse is moving.
And those things are kind of
hard to debug in the debugger.
You often have to resort
to printf debugging
because you don't want to
constantly be switching context
between your app in the
page and the Web Inspector.
So you often result to printf
debugging and you're cluttering
up your console with thousands
of lines and it's hard
to decipher, especially if
you're debugging multiple areas
that are not related
and you don't care
about the interloop data.
So this is where
Breakpoint Probes comes in.
It let's you see these
properties that you might care
about without having to
breakout into the Web Inspector.
So let's just go ahead
and give a demo of this.
So let's go to Safari here.
And I have a simple
stack the block game
that I want to-it's been a while
since this was written so I want
to see what's going on.
Let's go ahead and use the
Timeline panel for this.
I'll go ahead and bring
up the Web Inspector
in the Develop menu,
show Web Inspector.
And we'll go to the
Timeline panel.
And by default, the
Timeline is empty.
It's not recording all the time.
And it only automatically
records when you reload the page
or when you press the Record
button up here in the corner.
And this can record
any length of time
that you would like to record.
But when you-when
I reload the page,
it will only record
a little bit.
So I'm just going to go ahead
and start recording here
and see what this page is doing
as I interact with this game.
And you'll see the
events and all the work
that the engine is
doing in response
to these events start
filling up on the Timeline.
And I'll go ahead and stop this.
And my application has three
scripts, but the logic is all
in blocks.js, all the other
stuff is stuff I didn't
even write.
I don't even know
what's going on there.
So I can ignore those, but
they're doing some work.
And normally that
would clutter up my UI.
But they're collapsed here, so
they're not taking up any space.
I'll go ahead and expand the
script that I care about here
and I can see that Timers are
firing pretty-at a pretty good
clip as I'm interacting with
the page and there's key events
that are firing every
time I press a key.
Some of the other new
features of the timeline here,
we can now zoom and scale the
overview panel so if you want
to dig in to see where things
are happening across domains.
In this case, we have three
Timelines, the Network Request,
Layout and Rendering,
and JavaScript.
And all three play a key role
in the performance of your page.
So if you see anything
interesting happening
in a specific time range,
you can zoom in on it,
make a selection and that
information will show
up below in the Timeline.
And you can also drag this
around to scroll and scrub
through your time as things
were happening on the page.
So in this case, let me reload
and I'll show you the networks.
And in this case,
it's a local file.
But we now have network load
information and you see those
on the network timeline
and you'll notice
that the Timeline just
automatically stops
recording there.
It records up to
a certain amount
of time unless you manually
hit the Record button again
to record more information.
So let's look into the
network timeline here.
And we can see all of
the network details
that you might be familiar
with in the previous
network timeline.
They're all there and you
can sort-sort these columns
by whatever information
you find most interesting.
If you're looking for a
large script, you can sort
by transfer size and see
the biggest script show
up right there.
Let's go back to start time.
You can also do-click
on the other timelines
and get detailed tab-linear data
of what was happening
in that time range.
And again this is
all time range-based.
So you can see, as these layout
and rendering events filter out,
they disappear from
the display below.
JavaScript and Events
is a special view.
And if you're looking
for the old profile data,
this is where it's moved to.
So as you're recording Timeline,
we would now capture profiles
of all those entry points
into your JavaScript.
So whenever script is evaluated,
you can expand these to see all
of the functions that
were called in your script
and how much time each
individual function took to make
up that piece of
that entry point.
So that's a brief
glance at the Timeline.
But there is one cool thing
that people always forget
about when they're
talking about the Timeline.
And that's the Filter.
The Filter bar is
vastly underappreciated
in the Web Inspector and even
Xcode where it comes from,
where you can filter
down this list
to find what exactly you want.
So, in this case I'd look-I
did a filter for event
and it found addEventListener
right there
and it brought it to the front.
It expanded those
profiles and showed me
that exact function
I was looking for.
So that's the Filter
Bar and I encourage you
to start using filtering
more often
in the Web Inspector
and even Xcode.
We'll go back to my
block application
and bring up the Web Inspector.
And let's go ahead and go to
the Resource sidebar here.
And I really want to improve
this key function listener-this
key listener.
It's using key code,
which is pretty arcane.
And there's some new API
key identifier that's been
out for years that I could use
that would give string
representations
of these-for my cases
instead of the numbers.
So what I'll do, like I said,
when we set a breakpoint anytime
that key is pressed it's
going to interrupt my process.
So now to do another key,
I have to hit Continue
and log what I wanted.
And press another key, figure
out what I'm doing here.
But with this breakpoint we
can add a breakpoint action.
And I'll go ahead and edit this
breakpoint, which will bring
up the breakpoint
Action popover.
And let's go ahead
and add a probe.
So we have a few
actions available.
I'm not going to cover them.
But they're pretty
self-explanatory.
Probe Expression in
this case is brand new.
And we'll go ahead and
evaluate an expression
that we're interested in.
And we have an an event object
here and I want to know what
that key identifier is.
And that's all I need to type.
And I want to automatically
continue after evaluating
so it doesn't pause
in the debugger.
So we'll go ahead and
break out in here.
And when I added that probe,
it added a new sidebar
item called Probes.
And this is where that data
will show up in the table.
So I'm going to go back to
my game and interact with it.
And now it's logging that key
identifier every time I press
the key and showing
me the values
that I can now take an input
into my code and improve my code
and I didn't-this would have
been a back and forth process
or a lot of assumption of
what these identifiers were.
Now I can see them all
in a table and go back
to my case and modify them.
So that's Probes.
So that's a little bit
about Breakpoint Probes
and Source Code Timelines.
And I encourage you to
play around with them
and see how they can fit
into your debugging workflow.
So now let's talk
about Accessibility.
A new in the Web Inspector,
we have an Accessibility
Details View.
And this is pretty,
pretty important.
If you're working
on a major website,
you want to be accessible
to everyone.
Apple cares a lot
about accessibility.
And we do a lot of work to
make accessibility matter.
But it only goes so far as
to how much you put into it
when you're developing
your own applications.
And that goes for
iOS applications
and web applications.
And on the web, we have
something called ARIA.
And it's recently hit
a milestone ARIA 1
or it's about to.
And that allows you to
define for a DOM node what
that DOM node does as a role.
And those roles are
translated into things
that the person using the
computer with VoiceOver can hear
or see with your-with
your web application.
And in this case,
I have a webpage
that has an alert,
an HTML alert.
And those are notoriously
hard to debug or hard
for a sighted-non-sighted
person to see when they pop
up in a webpage because they're
not going to be able to see
that content unless you
annotate it with ARIA roles.
And in this case, the
VoiceOver machinery
and the Accessibility machinery
in web view exposes a lot
of details like child
relationships.
And these relationships are
not necessarily the same
as a normal DOM node
relationship
where your parent could be
someone that's deeply-a deep
ancestor of you.
And we show those
in the sidebar here
as a parent-child relationship.
And they're all linkable.
So I can click on
them and go directly
to these other child nodes
that are part of my alert.
And see that this button has
the right role for a button.
And it will allow people-it
won't allow people to focus it,
but it allows people
to click it.
And that's a brief
summary of what you can do
with the Web Inspector
and Accessibility.
There's a session
tomorrow morning
that covers Accessibility
and the web.
And I encourage you
to go check it out.
If you have a website or
a web view in your iOS
or Mac application, please
do make it accessible.
So that's accessibility details.
Now let's talk about
something that's really fun,
which is Color.
Color is one of those things-we
as people can understand
numbers.
But colors, there's
millions of them.
And it's very visual and
a very personal process
of picking the right color.
And if you're like me and
you're working on a webpage,
you might have a
client come in and say,
"I want this color salmon"
or "this color taupe."
It's hard for them to take those
words and you can translate
that into the right color.
Wouldn't it be great if you
can just bring up the color,
pick it right there
in the webpage
and modify it right
there in front of them.
So that's what we've added
in the Web Inspector,
and I'll give you a demo.
So I have an icon that
I've been mocking up.
And often I do these
things in the web
because that's something
I understand.
I can play around
with it a lot easier
than maybe I could
do in Photoshop.
And this icon is a little small
so I'll just go ahead and bring
up the Web Inspector here.
And I have a class
that I can add
to make it a little
bigger for you.
So, now I have my icon.
It has a couple colors.
It's got this color
for the glyph
and it's got a gradient
in the background.
I can bring up the Style
sidebar and see those colors.
And in this case, I'm
using some named colors.
CSS has hundreds
of named colors.
But maybe it's not
the right teal.
That's a little more
green than I expected
or the light blue is
not enough sea foam
or whatever your client is
telling you to make this color.
So, I can click on these colors
swatches and get a Color Editor.
Or I can switch over
to the CSS resource
and get the exact
same experience.
But in this case, we want
your source code to be front
and center, so we don't even
add those color swatches.
But we have a new feature
that let you get a data
detector-like experience.
When we detect that
it's a color,
we will show a color wheel
next to it as you hover it.
And when you click
on that wheel,
we bring up the color popover.
And in this case we
could just click around
and you can see the color
updating live right there
in the web page.
And I can find the right color
that I'm looking
for, for this glyph.
And if it's a named color
it will default back
to the named color syntax.
But if it's not something
that's named,
it will just give you
the RGB syntax or RGBa
if you picked an alpha.
But we didn't stop there.
We now let you do gradients.
And gradients are even more
hard to visualize than color
because you have that interplay
of the colors transitioning
from one to another.
And it's hard to see
those in your mind.
But we can go ahead
and edit this gradient.
And it gives you a simple slider
that you might be familiar
with from other UIs.
And I can drag these around
and you'll see it's updating
the source code as I drag this.
The percentage is changing.
And when I let go, it
updates the page live.
So I can see exactly what
is applying to this page.
But you can't just
edit the color stops.
You can edit the type of
gradient or you can pick radial
so it's coming out
from the center.
And I can click on these
colors and get the color wheel
and start editing each of
these color stops directly.
So I can find the exact
look I'm looking for.
Drag this around.
Maybe we'll run it to be
more of the starburst look.
A little bit more yellow.
Or the client might say, "Oh,
I want a linear gradient
in this case."
So let's go back to the
traditional iOS look
for gradients and start picking
some pretty wild colors here.
So that's the gradient editor
at the new Web Inspector.
And what I didn't show you here,
let's go back and reload here.
If I make any of
these changes, say,
I want to go back and save it.
Let's make this a red
and that looks good.
That looks like a sunset.
In the Web Inspector, I can
just go ahead and hit Command+S
that will bring up the
traditional Save dialogue.
Go ahead and replace it.
And now, if I close the Web
Inspector, reload the page,
I have that gradient
color right there.
The icon is a different size
because I was modifying the DOM
and it that doesn't save.
But if you're editing
a CSS resource
or any other local file resource
you can save those right back
to disk from the Web Inspector.
So that's Color and
Gradient Editing.
And I hope you play around
with it and try it out.
It's really fun to just get down
and dirty with those colors.
And the gradient
syntax is something
that I still have
trouble remembering.
But the Web inspector will
just help you right there
and get the right
syntax and let you go
on to do more important
things in your code.
So that's the summary
of all the new features,
and just a brief introduction
of all the new features
in the Web Inspector.
So, I encourage you
to take advantage
of the new JavaScript
language features.
As you're able to release and
use the new modern browsers,
or use iOS 8 exclusively, or
Mac OS Yosemite exclusively,
you could start using some
of these new language
and syntax features.
The Web Inspector is
now available again
from your Mac Applications.
If you have a web view
that you've always wanted
to see what it's doing
in your application,
there's been a few
ways to do it.
But you can now officially
use the web inspector
in your Mac Application.
And I want you to
enjoy debugging your
JavaScript context.
This is something
that may seem simple.
Oh yeah, there's now a debugger.
But, yeah, now there's
a debugger.
You can now debug this
JavaScript that's been plaguing
you or giving you this weird
errors or it's always been hard
to debug these contexts because
there's been no debugger that's
been able to give
you that information.
And again, it's really important
to make your web
applications accessible
and your iOS application
accessible.
And be a colorful person.
Enjoy color editing in the Web
Inspector and gradient editing.
And again, for more information,
you can contact Evangelism
at this email address, or the
Developer Technical support,
and even the Apple Forums.
I'm in the Apple Forums
if you have a question
about the Web Inspector,
or anything web-related,
or one of our team will be
able to answer it or I would.
There-Again, there's
a couple more sessions
that might interest you as web
developers or iOS developers
that have web or
JavaScript context.
You can go to the
session tomorrow morning
and learn all you need to
know about accessibility
in your web application.
And then stay in that
same room and learn
about responsive web design
for making your web apps scale
from desktop size
to iPhone size.
And that's it.
Thanks a lot.
[ Applause ]