WWDC2004 Session 413
Transcript
Kind: captions
Language: en
for 13 plugging development for Safari
and WebKit Chris lunenburg to
re-engineer so first of all what you're
going to learn here well first of all
you're going to learn what our plugins
in case you don't already know then I'm
going to go into why you develop plugins
the typical reason for wanting to
develop plug-in is to extend the
functionality of a web browser but
you'll suit you'll soon see that there
are other reasons as well I'll go into
how to develop plugins I'll go into the
types of plugins that you can develop
and then the issues involved with
developing those plugins and then I'll
discuss using plugins in your web page
that will involve the right kind of HTML
for embedding your plug-in on a web page
as well as scripting your plugins from
JavaScript so what our plugins well
plugins are libraries typically they're
written by third parties you may be
familiar with photoshop plugins they add
filter effects images in Photoshop well
in web browsers plugins support content
types that the browser doesn't handle by
default for example without the apple
quicktime plugin you would be able to
see QuickTime movies in Safari and other
web browsers other popular examples are
macromedia flash and windows media
player so why would you want to develop
a plug-in well first of all you'd want
to extend web browsers as I mentioned
before you'd want to handle content
types that the web browser doesn't
handle by default and the other reason
for 12 to write a plugin for a web
browser it's a basically run native code
from a web page you can display HTML you
can run JavaScript but in some cases you
may want to run some native code to get
some sort of rich browsing experience
and the other major major reason for
providing a plugin is to extend your
WebKit application if you have a web
chat application the only way that you
can get a widget inside of a webview is
to you know write write a plug-in for
example mail users plugins for their
file attachment widget or they will be
using plugins for their file attachment
which it in mail messages
and dashboard widgets can dashboard
widget can use plugins too so I think
you have about 24 hours to get a
dashboard widget working and you
probably get a pretty cool and if you
use a plug-in so this is the biggest
part of my talk here it's how to develop
plugins first of all I'll be covering
the two types of plugins or the two
types API is that you can use to develop
a plugin first of all I'll be discussing
the Netscape plug-in API it's been
around for a number of years I'm sure
that most of you are familiar with it
and then I'll discuss the WebKit plug-in
API which is something completely new
and I'll go into depth about that
shortly then I'll discuss a bunch of
things which relate to both kind of both
kinds of plugins that is using blood are
using bundles which is how you represent
and how you package up your plug-in on
disk and then registration which is how
you actually register your plug-in with
the host application then i'll go into
installation which is basically where
you install your plugin so here in this
wizzy graphic here you can see that
there are two types of plugins that work
in Safari and WebKit there's an FJ
plug-in and there's a WebKit plugin
first I'm going to focus on the Netscape
plugin so before I go any further about
this I'm going to discuss history so the
Netscape plugin api has been around
since 1996 he was introduced in netscape
2 point 0 microsoft inter explorer
shortly after started adopted it in
their version 3 pointer it's used by
many web browsers out there if not all
web browsers it's always been supported
inside of Safari actually so here's what
the Netscape plugin api provides it
provides a drawing API so that you're
plugging those when and where to draw it
provides an events API so that your
plugin can receive user events it
provides a networking API so that your
plug-in can send and receive network
streams so before I go in depth about
any sort of API so I want to discuss an
issue about the actual file format of
your plugin well on macro Senate plug-in
or library can be compiled in two
different ways
it can be compiled in ma co or pests AKA
CFM file formats well we really like it
for you to use macco it's the native
object file format on Mac OS 10 CFM is
really something of the past back in the
classic days Marco plugins load much
faster than CFM plugins in fact when the
quicktime plugin was ported over to
Matco we found that it loaded 100 times
faster new api is on the system are only
going to be provided or only to be
available to Marco applications and
libraries it they won't be available for
CFM applications and libraries and you
can develop and debug a mock go plug-in
inside of Xcode that can't be done with
CFM so here's the big news we're
extending the netscape api we're adding
more stuff to it first of all we're
adding a scripting API which is the
ability for your plugin to be accessed
from javascript and from your plugin you
can get the JavaScript and the rest of
the document we're also adding an API to
access HTTP headers this is a kind of a
developer request here this allows your
plugin to get up the HTTP headers which
is the all basically all the server
information besides of the content also
we're adding a state information API
this is an API that allows you to get
the state of the plugin inside of the
web page that is whether the plugin is
in the frontmost tab or not whether the
window is from most window or not
whether the windows minimized or not and
we're having much more expected much
more to expect here a lot more from us
and what's important about this is that
this is not just an apple thing we're
we're working with companies such as
Mozilla macromedia and opera to
basically get this new API working in
many web browsers and many plugins out
there so here's my with the netscape
scripting graphic so i'm going to
discuss Netsky of scripting this is
basically the only new netscape api that
i'm going to discuss today so what is
what is scripting well it allows
JavaScript to access your plugins and it
allows plugins to access jobs
script and the rest of the document so
the Netscape API used to actually
provide this functionality in a
technology called live connect live
connects is a Java API it's pretty slow
because it involves starting up a Java
VM and involving Java and it's rather
simple communication between the plugin
and the browser in WebKit lab Connect is
only used for Java applets we don't
support there for communication with
plugins well in the new API it's a capi
that is it's just like the rest of the
netscape api it's all based on C and
it's much faster than live connected so
i'm going to talk about i'm going to get
more in depth about the scripting api
here but first i'm going to discuss the
communication from javascript to the
netscape plugin so when javascript
encounters your plugin in a script it
will call npp get value to get the NP
class and the NP object which represents
your plugin now the NP class you can
think of at the interface between your
plugin and javascript and empty object
is the is you can think of that as an
instance of your NP class I'll get more
into that shortly so here's an example I
hope you can see that here's an example
of MP get value in this case if the
variable that that the browser is asking
the plugin for is NP p v plugin
scriptable and p object i then return an
empty object which represents my plug
into javascript and here's MP class so
empty class is basically a struct
consists of a struct version and a set
of function pointers which define the
interface between your plugin and
javascript first of all there's allocate
the allocate function is called to
allocate an NP object the allocate is
called to deallocate that empty object
invalidate is called when javascript no
longer is using your NP object
has method is called when javascript is
calling your is calling a method on your
FB object to make sure it actually has
it invoke is called to invoke a specific
method on your NP object and has
properties called to check if your NP
Asik has the property get property is
called to get at a value for specific
property set property is called to set a
value for a specific property and here's
an example of empty object in this in
this case my empty object is a movie
object it basically contains an MP class
and a reference count though so that the
required fields of the of the struck
there and then everything that follows
is basically anything else that I want
to have in that empty object so what you
can see here what here what you see here
is my movie object this is basically
what well how I represent my plug-in in
JavaScript so here's an example of movie
allocate my allocate function basically
allocates the movie object and returns
it to JavaScript and here's an example
of MP invoke my excuse me moving evoke
which is my movie which is my invoke
function so if javascript is calling
play I just call play movie which is an
internal function within my plugin it's
javascript is calling pause I just
called pause movie which is an internal
function within my plugin and you know
before I exit this function I said a
return value in this case well in either
case i have no return value so I said
I'm defined so I've discussed the
communication from JavaScript to the
plug-in now I'm going to go in the
opposite direction and that's from the
plug in the JavaScript so the way this
works is that if your plugin wants to
get a javascript the interpreter and the
rest of the document it's basically
called NP NP n get value to get the
window object using the variable name
here NP n v window NP object so once it
gets back once it gets back this window
object it's basically an empty object so
I can start making NP object calls on it
for example i can call create object
which creates an object i'll actually
need to implement this in order to
return an object back to javascript if i
ever need to do that retain object in
case they want to keep a specific object
around for a while and of course for
every retaining it video really so
there's release object and here are my
invocation methods there's npn call
which allows me to invoke a specific
method on an empty object and then
there's npn evaluate which allows me to
take a string a javascript string and
evaluate it and get back a result and
here are props at property access
methods which allow me to get to actual
properties of NP objects so there's npn
get property which returns a property
for of an env object set property which
allows me to change your property of n
empty object npn remove property which
allows me to remove a property of an NP
object so let's do a little demo so I
need to drink ok so what I'm going to
show here is my little netscape plugin
it's called netscape movie plugin it's
basically it's basically just like the
quicktime plugin just a little simpler
and what i'm going to show you here is
i'm not going to go too in depth with
the code here as you can see it's pretty
complex it takes a good amount of code
to basically get a simple plugin up and
running an sk plugging up and running in
WebKit so what i want to show you
actually here and this in this file is
the number of lines of eggs it takes
about six hundred twenty six lines to
get a simple plug-in up and running so
remember the number because it's going
to matter a little later in this
presentation so let's give this guy a
try cross figures
so as you can see here I basically have
my little plug in working in here on
this web page this is not the quicktime
plugin i don't even have an assault so
on this page i have the plug-in and to
form elements playing pause now these
form elements actually cause calling
JavaScript functions on my movie
[Applause]
[Music]
BMW introduces the first seamless
integration of my ipod and automobiles
so that's it so you can actually
download that plugin from connectable
calm and use it as a template if you
want to to the presentation machine
please okay okay okay so I've discussed
the development of an Etsy a plugin so
now let's focus on the development of a
WebKit plugin well the website plugin
api is an objective c api the cocoa api
it's very simple both cocoa and the api
the plugin api itself are very simple to
work with any WebKit apne web keep
plugging that you work that you develop
will work inside of a WebKit application
so here's what the WebKit api web chat
plugin api provides well first of all
your plug-in and every instance of your
plug-in is an NS view so there's no
explicit API for dealing with events or
drawing that's all done the NS view it
there's no explicit API for for URL
loading because you can do that very
easily yourself using nsurlconnection
which is a foundation api another thing
that this api provides is access to web
key classes such as web frame so that
you can have a closer interaction with
with WebKit if you choose to have that
and also it has a scripting api which is
which is basically web gets new script
api which was discussed in depth this
morning but i'll go into that shortly so
here's the first message that your
plugins should implement it's called
plugin view with arguments this is
actually the only method that your
plugin needs to to to implement so as
you can see it's it's very simple to get
one of these up and running so plugin
view with arguments basically returns
your plugin view the plugin view which
should which is supposed to be inside of
your inside of your web view and there
are some other plugin methods
now these are all optional you can
implement them if you want the first one
is web plug-in initialize this method is
called soon after your plug-in is
created in this method you basically
start allocating resources and doing
that sort of thing then there's web
plugins start in this method you start
doing work you start animating the
members will plug and stop in this
method you stop doing the work you stop
you cease all sort of animation then
there's web plugging destroyed in this
method you destroy or D Alex any and
release any sort of resources that you
might have or you can just wait until
you get the d alec method and here are
some other methods that your plugin can
implant first of all there's web plugin
is selected so this is called when your
plugins selection state has changed so
if you are selected you probably want to
draw some sort of selection state and
here's object for web script this is the
method that returns the the object which
represents your plugin in javascript and
i'll go into that shortly so here are
the container methods these are the
methods that from your plugin you can
call on to the container so first of all
there's web plug-in container loader
question frame this basically tells the
containers will to load a specific web
page and a specific frame oops okay then
there's what plugin container show
status if the container such as Safari
it has a status bar it should show some
sort of status message that bottom of
the page at this point then there's web
plug web plug-in container selection
color so if your plugin is selected it
should use this selection colors to draw
some sort of selection state and lastly
there's web print so from your plugin
you can get the web frame which contains
the plug-in from the web frame you can
get to the web data source in the web
view and all the other web heat classes
okay so now i'm going to go to WebKit
scripting this was cover this morning
but i'm just going to brush over this
right now first of all I'll go I'll go
into scripting from javascript to your
WebKit plugin
so when javascript encounters your
plug-in object it will call object for
web script to get the reference to plug
in the objective-c representation of
your JavaScript object now that object
that is returned I can choose to
implement these methods first of all
there's web script name for selector
which allows you to choose a name given
a selector that your object implements
and then there is selector is excluded
from web script and this method you
basically decide which methods you want
your plugin to implement now this method
is pretty important as far as secure as
far as security is concerned because you
only want to export methods that you
think are secure will crash the page and
what have you so here's an example of an
implementation of his selection excluded
from web script in this case I'm
allowing the play method on my plug-in
to be exported and at the bottom there
is just the simple limitation of the
play methods then here are some methods
about property access first of all
there's web script name for key which
allows me to choose a name given a
property on my what on my on my plug-in
object and then there is key excluded
from web scripts and just like the
previous method or like the message that
dealt with with with JavaScript methods
and here I choose which properties I
want to export to JavaScript so there is
an example is ski excluded from web
scripts in this example I'm allowing
muted the muted property of my object to
be exported and at the bottom there are
some methods which allow the key value
coding to access my music property okay
so i've just i've discussed scripting
from javascript to your website plugin
now let's go in the other direction
so from your plug-in you can get at the
document or the window object in two
different ways you can call windows
script objects on web view which which
will return the opposite ectasy version
of the JavaScript window object or you
can call domdocument on web frame which
will which will basically be the dom
document which contains your plugin so
here's the interface for windows script
objects on web view as you can see here
it returns a web Script object so I'm
basically I'm going to just show you now
a few methods that web web script object
implements or provides first of all
there's set value for key which allows
you to set a specific value for a
specific key on a web Script object then
there's value through T which allows you
to get a value given a key there's
called web script method which allows
you with arguments which allows you to
invoke a specific method on a web Script
object there's evaluate web script which
allows you to evaluate a javascript
string and then here's the interface for
getting the domdocument off the web
print as you can see here it returns a
dumb document object and here's just
kind of a hodgepodge of methods that
domdocument implements and provides
actually these methods are also Dom node
methods because Dom document is a
subclass of Dom node so here's
attributes this allows me to get the
attributes of the document or dom node
here's paranoids because you me the
paranoid of a document or dom node child
notes gives me the children of dom node
first child during the first child of
dom node is a rather self-explanatory
last child gives me the last child of a
dom node previous sibling so on and so
forth so for more information about the
domdocument Dom nodes I suggest you go
to this talk on the Friday at ten-thirty
I'm not sure of the numbered maybe want
to give us me for 26 and that'll discuss
the Dom document and all that as well as
editing if you're interested in that so
let's do a little demo of a WebKit
plugin
so I'm not very original my web keep
pluggin does the same thing as my
previous plug-in does it's called WebKit
movie plugin but remember that the
previous plug-in did everything in about
600 plus lines of code this does it in
137 so as you can see is extremely easy
to write one of these puppies so I'm not
going to go into the code here but I'm
just going to go into a little demo of
it
[Music]
ah
I
[Music]
okay so you may be thinking now okay he
just did the same demo two times in a
row that's pretty damn boring okay so
let me try to spice it up a little bit
wouldn't it be cool if I could somehow
control the play rate of that movie you
know control how fast it plays from the
web page so I'll go down to my plug in
here and enable my set play rate
function and the very important step i
exported it to the Java strict
JavaScript here in this method give it a
little compiling it works and then I'll
go into my HTML file and enable a slider
which is a kind of new form control that
is sort of WebKit specific and as you
can see here my slider basically just
called set movie player right which is a
JavaScript function which calls my
plugin and let's give this a try oops
hey it's beta let's give him that
[Music]
okay so okay so that's my whip keep
plugging demo so I've discussed those
types of plugins that you can develop
for Safari and WebKit let's give them a
little comparison so first of all the
Netscape plugin api is the capi it's
cross-platform the same API will work on
Windows Linux in the Mac it works in the
most brought most web browsers out there
in fact it probably works in all web
browsers out there and the WebKit plugin
api is at coco Objective C API it only
works in WebKit applications it's
possible that it may work in other
applications in the future and as you've
seen here it's very easy to develop one
of these things so now I'm going to get
into some issues that relate to both
texts of eight both types of plugins
well first of all plugins on disk are
bundles well what is a bundle a bundles
a folder which contains the library that
is the compiled code of your plugin it
contains resources which are the
resources that your plugin may want to
use such as images and those types of
things it contains localizations so
you're plugging can be localized in many
different language a single plug-in
bundle can be localized in there are
many different languages and lastly
contains registration information so
that your your plugin is probably
registered with a host application so
let's get into registration information
well you're plugging is responsible for
registering the contents that content
types that it can handle that
registration information can be sort in
two different ways the first way and the
way these days or the way that it's
always been done is with carbon resource
files the new way is with info booths
with the info.plist file basically the
info.plist file is you're probably all
familiar with it but it's just a very
easy way to edit and maintain metadata
for your application or a bundle on Mac
OS 10 this is a modern way of actually
doing it working with carbon resource
files tends to be a big pain so if you
care currently fop those files only work
in WebKit applications but if you care
about working with other browsers as
well on the Mac you can use both and
that will work just fine so let me go
into registration via the info pedophile
first of all you want to provide the
description of your plug-in which is the
user-visible description of your plugin
then you want to provide a key and value
for the name of your plugin which is the
user-visible name of your plug-in and
lastly you want to go into the mine
types at your plug-in can handle so
within that mine type you want to
specify the extensions that map that
mime type as well as a user visible
description for that mime type so with
all this information you'll be able to
register your plug in nice and easily
inside of a whooping application now
that may looks a little complex it
certainly does to me but inside of
property list editor it's very easy to
write one of these things so you've got
your clear plugin compile it's got all
the registration information all set up
where do you install this thing well you
can install in three different places
you can install them / library /
internet plugins so that it works with
all applications for all users you can
install it until the library / intended
plugins so that it works for all
applications just for that specific user
or you can install it in the plugins
directory of your application so only
work inside of that application so this
is the last part of my talk here this is
actually how to use your plugin i'm
going to first discuss the good kind of
HTML for embedding your plugin on on the
on a web page and then i'll discuss how
you script your plugin from javascript
well most web browsers out there support
the embed tag it's a sufficient way of
embedding a plug-in on a web page but if
you have a windows version of your
plug-in you'll need to that
need to use the object tag well it's but
it's possible to use HTML that does both
and and thus works with all browsers
here's the embed tag I'm sure you've
seen it all before and here's the object
tag subscribed by windows and / am tags
which are children of the object tag and
then the embed tag which is also a child
of the object tag and that's basically
it so with it's a little somewhat
lengthy HTML snippet here you can get
your plug-in working on all browsers so
let's get into scripting now from
javascript basically each instance of
your plug-in on the page has a
JavaScript object which represents it
you can get at that JavaScript object by
name or by number once you actually have
it you can call the exposed methods on
it as well as the exposed properties so
here's a little sample this is actually
taken right from my demo here Here I am
getting a plug-in by name since I know
that excuse me by number since I know
that it's the first plug-in on the page
I can just use index zero on the embeds
array and then here's an example of me
using or calling a plug-in method which
is play and then here's an example of me
getting a plug-in by name you don't see
it here but my embed up my bed tag
actually has a name attribute which is
movie plug it and Here I am getting it
by moving movie plug-in and at the
bottom layer I am actually getting and
setting a plug-in property so everything
that it discussed today is going to be
available on safari is available on
safari web get 1 point 3 beta on Panther
you can download it now at connectable
calm it's also available on your tiger
seed that you got today except for the
new netscape scripting api so those are
only available on the panther beta now
once both the Panther beta or once both
the Panther and tiger version of Safari
GM everything that I mentioned today
will be will work in both so for more
information you can go to connect at
apple com to get sample code links and
demos you can actually get the demos
which I showed you today and you can use
them as templates if you want you can
also go there for new documentation for
WebKit and lastly at the bottom there
you can go to that web desk ape URL to
get information about the Netscape
plug-in API that doesn't actually
include the Nets the new API to get at
those and for information about those
you need to actually use my my demos I
gave today