Mac OS X Essentials • 49:47
Discover how the WebKit framework's Objective-C and JavaScript APIs allow you to add a rich, in-page HTML editing experience to your desktop or web application. Learn how to "roll your own" or integrate with other WYSIWYG HTML editing libraries.
Speaker: Tim Hatcher
Unlisted on Apple Developer site
Transcript
This transcript has potential transcription errors. We are working on an improved version.
Welcome to Session 131. I'm Tim Hatcher. I'm going to talk to you about WYSIWYG editing and adding it to your webpage or your Cocoa application.
( Cheering )
( Applause )
( Laughter )
But according to the source of all truthful information, Wikipedia, this is from the Flip Wilson Show back in the sixties or seventies where this is what he would say when he was being quirky or funny about something, about his personality.
And it's been picked up through time by computer engineers to talk about laser printing and then on screen editing, is what we're going to be talking about today.
( Period of silence )
So there's a couple examples of this I have on screen. One's a webpage and one's a Cocoa application. It's starting to get hard to tell the difference nowadays what's what. So I have Gmail and Sanvox by Karelia, both used WebKit. One's in Safari and one is a Cocoa application using a WebView.
How many of you guys are HTML editors or HTML authors and how many of you are Cocoa, Cocoa people? Let's see a show of hands. So HTML editors. Cocoa. All right. So we've got a good mix. So we're going to talk about HTML first and then go into some of the Cocoa stuff with WebView later. The Cocoa guys don't sleep because a lot of the end page editing can now be used in your Cocoa WebView. So you can do a lot of mix and match. So keep an ear out for some useful information and a lot of the concepts are similar.
So like I said, it all starts with Safari. Safari's the front end for WebKit. You think of WebKit, you somewhat think of Safari too and we had a lot of big announcements this week about Safari and WebKit and that's all related to the engine. The engine's been available since 2005 or 2003, I can't remember. It's getting old now and it's grown a lot and we've added a lot to the WebKit engine for you all to embed in your applications and take advantage of in Safari as a webpage author.
It's also a great Open Source project if you're interested in Open Source and contributing back and helping out. We've seen a lot of interest in HTML editing in the Open Source arena, where authors and people using editing have come in and helped file bugs, fix things that they have pet peeves about and just help out and contribute in any way possible and that's been great.
So there's three things I want to talk about today. I gave a little summary, we're going to talk about the fundamentals of HTML. What it means to use HTML. Then we're going to talk about in-page editing in particular using JavaScript and in your webpage. And then get into some of the Cocoa stuff. But the Cocoa people, don't sleep please. You're going to find a lot of interesting things in the in-page editing part.
So let's talk about the fundamentals of HTML. As you all know, HTML is a mark up language. It's a tag based, it's been around forever for some of you and it's basically all over the place now. It's sprung up with XML now and there's all sorts of places you see HTML and HTML-like things such as XML. So you should be a little bit familiar already just in passing. But the general concept of HTML is it's a tree-based structure.
Here's an example of a simple sentence that has some HTML formatting applied to it, some italicize, some bold and some underline. But that looks like this in HTML. You have all your tags. The tags can be nested inside other tags, so you start getting a tree. You have your nodes, your text nodes, your element nodes and they just keep nesting deeper and deeper depending on how nested your content is. So this is the full tree for that example that I have up above.
And this is nonsemantic mark ups so some of you people might want me to use them or other semantic tags instead of the bold tags. But this is simpler for the slides. There's another type of structure which is the flat structure. Those of you on the Cocoa land familiar with NSAttributed string, will know this structure because it's all about ranges and attributes. So you have text ranges for all the different properties that you're wanting to apply to this string character by character. There's some disadvantages with this though.
Sorry about that. Where is you make any changes in this string, these ranges have to move. If you change in the middle, it's just going to keep moving your numbers around, you don't have a good separation of content and presentation which HTML gives you. So HTML has some advantages and it has a lot of advanced layout capabilities. We've talked a lot about CSS here before and a lot of the great features of HTML and CSS that are constantly evolving.
So now let's go in and start talking about in-page editing and how HTML applies in in-page editing. Of course, there's a lot of ways to do editing and this is very particular about in-page editing with HTML. You Cocoa people are more familiar with NSTextView and I'll talk about the similarities there but just keep that in mind. in-page editing, word processor, that's what we're talking about today.
So on the web, there's a lot of adopters of in-page editing. There's the new Leopard Server Wiki which this is a screen shot of, has a nice editing tool bar that lets you apply bold, italicized text without having to look at any mark up or tag around that text. It's what you see is what you get. That's the concept.
Google has been doing it for a while in Gmail and now with their full docs feature, their application. Application on the web and that's what we're targeting the iPhone with. Applications on the web. Hotmail, eBay and WordPress have also adopted this and it's just growing. People are adding it everywhere.
There's a lot of people that still used form fields and plain text fields on the web, that's the old way to do editing on the web where everything's plain text and it's a form element and start thinking about new ways to integrate this editing that I'm talking about today into your webpages that you're designing.
So when we're designing these sites or testing these sites, we constantly run into this message and if you're a consumer and you're visiting these sites, you always run into oh, Safari's not supported. What's that mean? Why isn't Safari supported? Are we lagging behind? Well I'm happy to say, Safari 3.0 is the best editing experience there is. It started out with 2.0, 2.0 added it but Safari 3.0 has the full support of editing and I'll talk about what that means later on.
So if you're one of these sites that blocks Safari, I encourage you to go out and download the new beta that we announced Monday. Test on Windows, test on Mac, you have no excuse if you don't have a Mac anymore. You can test, test, test on Windows now.
So if you have one of these sites that's blocking Safari, please turn us on. We find that if we just go in to the debug menu in Safari and spoof is Firefox, it's just supported. It just works. So if you're looking for Safari, please unblock us. And if you're one of the visitors to these sites, send them a kind message. Let them know that Safari 3.0 is out there and that you can now test and use these new editing features.
So let's diverge a little bit and talk a little bit about proper browser detection. So these sites are obviously blocking Safari. They're obviously doing some browser checking to show that message to you, that Safari is not supported. Well I encourage you to test for WebKit, not Safari. WebKits used by many browsers on Mac OS X such as OmniWeb and Shira. You're just going to be either letting them in and not knowing it or just blocking them for no good reason. So if you're testing for Safari, you're really not testing for the right thing. So test for WebKit. But besides that, test for engine features, not the engine.
You don't want to be in the business of improving your browser sniffing all the time. Browsers change too quickly to keep up with your user agent checking. With you can do feature checking with the queryCommandSupported which I'll talk about later and JavaScript object detection, which I'll talk about later too.
So if you do have to check the engine, check for ranges or a number that never ends. Just a beginning number and in the future and I'll talk about that a little later. Because Safari now has a version that's in the 500 ranges. It was in the 400 ranges for Tiger but all of a sudden, once we hit 500, sites that were looking for 400, stopped working even though it's the same Safari, it's an even better version than WebKit. So keep that in mind when you have to do version checking.
So here's an example of feature detection using JavaScript object detection with the in operator. So the first example here and I'll talk about the selection object later, I'm just going to give you this example first. This is for WebKit. So we're looking for the getSelection property on the window object and if that exists, we'll get the selection object which can then be turned into a string later.
For Mozilla and Gecko, yeah Gecko and Opera, the getSelection property is the exact same name, but it's on the document instead of the window And IE has their own way of doing it, when don't they? They have a selection property on the document and then they also have a createRange function on that selection object to get the text of the selection.
So this is the IE trident engine and in the end, we're storing that in the same variable and then we can alert that to the user. That works in all engines. But this is the three different ways you can test. Notice none of these if statements say if Safari, if WebKit, if trident, if IE, there's none of that.
Maybe a browser will come along that has the getSelection object on the window and it's not Safari it just works, maybe they're trying to be compatible. That's what the web is all about. Everyone's trying to be compatible with each other. So some of these things might start working with other browsers and if you design your code right, it'll just work in the future.
So as a last resort, if you do need to do user agent sniffing, look for WebKit like I was talking about earlier and look for the engine and not the browser. The IE engine is used on other browsers on Windows. If you're just looking for IE, it's not going to work. Gecko is used in Netscape and Firefox. Opera is used in Opera and this is an example of the user agents. I don't want to stay much on this slide because I really don't encourage doing this at all. You really want to do the feature checking.
So now let's really talk about in-page editing. Now that we've gone off on a tangent. Now let's get into the meat of editing instead of how to test for browsers. So like I said, there's a lot of adopters lately and here's an example of a few. I really love the new Leopard Server Wiki; they've done a great job with making a nice, simple Wiki editor.
So there's two modes of editing: DesignMode and ContentEditable mode. And let's talk about the first one, DesignMode for a bit. DesignMode is the entire document is editable. Everything. You, there's no non-editable areas. The only way to mix editable and non-editable content is to use an i frame or some other frame. So in this code example, I'm turning on designMode for the current document. That means, whatever the current document is, it's just going to be editable by the user now.
And now here's our second example that has an i frame that I check for and find with getElementByID and get the content document and turn on designMode that way. So now that i frame is editable, but the document that includes the i frame is not editable. That's the only way with DesignMode, to mix content.
IE came up with the ContentEditable property, which Safari has adopted and I'll go into that in a bit. But this lets you have editable pockets. You can have your whole document and do all the fancy designs that you want and have these specific areas. This is closer to a form element than design mode is, but it's not a form element. So don't get confused by that. It will not, the content will not automatically get submitted with a form.
So it's as simple as that. Just contenteditable equals true and you can come in later in a nested block and say contenteditable equals false and that'll prevent any edits inside that sub-block, but there's a catch. That block is inside an editable area. So if you can get your selection around that block, inside the editable area, you can delete the non-editable area. So it's tricky. It's content editable. It's about the content, not about the block. So the block can be deleted, the content inside of it can't.
So that's content editable. Now here's the browser story, the compatibility story. Firefox only supports DesignMode and I have no idea if they plan to add ContentEditable in the future. But history tells us that browsers always try to be like each other so it might show up in the future.
IE has both. I was having trouble verifying DesignMode actually. I've read all over the place that it supports it, but every test I've tried say it just doesn't turn on. So who knows what that's all about. But there's always both that you can try in IE and Safari and WebKit supports both modes, beautifully.
And if you're doing this, try using DesignMode across the board and you can always have a frame that has a body that's content editable inside of it to trigger both modes and that won't confuse WebKit and that's how I ended up getting IE working. By having the body be content editable.
So when you're editing, there's all these commands that you as a user might want to do on some text, bold, italic, underlined and these are commands, command names that the engine supports. WebKit in particular. IE has the same command set and there's probably a few that both have and some don't. But this is the set that WebKit has.
So these command names you're probably familiar with doing command B, command i for italicize, that still works. If you're in one of these regions in Safari, you can just type your normal command keys that you're all familiar with. These commands are used by what's called the execCommand function and I'll talk about that on the next slide. But these are all the commands we support and they're always tied to a command key too. Most of them at least.
So there's a lot of text on this slide, but I've highlighted the areas that are important. JavaScript has a function on the body called execCommand and this is supported by all three browsers and what you do is you pass in one of those command names that was on the previous slide.
So if you want to design a fancy tool bar, a tool bar that has a bold button, italicize button, an underline button and font size and anything like that, you would execute one of these commands by name. So here's an example. I need to get the document, so I have my frame, I get the content document off of it.
I then want to check if that command is supported at all by the browser and to do that there's the queryCommandSupported and queryCommandEnabled. They're subtly different. Supported means does this engine support it at all and then there's queryCommandEnabled where maybe the current selection doesn't support that command, but the browser still supports it.
So you want to check for both and then maybe disable your tool bar button if neither of those return true. Then when the tool bar button's clicked, you'll just call execCommand and pass on the command name. execCommand also takes two other arguments that some of the commands use, but I won't get into that in detail. You can look that up online.
There's also a couple more query commands. This is for toggling state or seeing the current state of the selection. All of these functions operate on whatever is currently selected in the editable area. So this will give you an answer based on what the user has currently selected or the current insertion point if there's no range selection.
So the first one, queryCommandIndeterm, will tell me if the current selection has a mixed state of bold and not bold in this example and maybe I'm going to show my tool bar button in a special way to show this mixed state. Then the second one, queryCommandState, will return true or false if the selection has that bold. So if it's not a mixed state, we just want to check to see if bold is on or off.
And then we might want to toggle the tool bar differently. And then in the end, we'll just turn it back to it's normal class name and I'm not going to go into detail about what those other lines are where we're setting the class name, that's just standard CSS toggling of class and I went into that last year at another presentation.
So I'm going to give a demo actually of one of these tool bars I designed when I was doing this presentation. I wanted to show a nice tool bar and you're probably familiar with some of the other tool bars that are out there on the web, that look a lot like Windows 95, the ugly gray bezzled buttons. So I'm going to show you something special. Can we switch to the demo machine?
So this, this page up in Safari right now, is actually an editable area. If I click in here, it's going to give me a selection and I can start typing. But when I click, my toolbar just fades in. It's an editable area, but it respects the current focus of the user. So we don't need to show it all the time.
The user is not editing all the time. So I encourage you, if you are designing tool bars, fade them in or bring them in when the user actually needs them. No reason to clutter up the page when it's not in use. So like I was saying earlier, you can come in here and just start typing.
This is live text just like a text editor and this is actually an i frame so it scrolls and you can go in here and I'm going to hit command b, maybe I want to italicize some things and you can see up in the top, my tool bar buttons are respecting it.
I didn't even go up there and touch it, but I'm responding to these changes and I'm toggling my tool bars using the queryCommand functions I talked about. So when I change selections, the tool bar hides, I can get an insertion point, the bold button comes on, changing the justification.
So let's also add a link. So now we have a link to apple.com here and you can click it open link. Links now in Safari are disabled by default. So I can get in here in an editable area, they're disabled. I can get in here and make any changes while this is linkified and it's not like a hat trick trying to get your selection around this link. Before it was a really difficult to make a selection while the link is live. You would all of a sudden be going off to this other page. So that's another change in WebKit in the 3.0 version.
We can also get in here and insert an image. I have a default image in here and that's the Safari logo. This is all drag and drop. This is how powerful our editing support is. It's just like a text editor. Just like you would be in text edit. You could do all this same things in text edit. This is in a webpage. You can do whatever you want, put any chrome around this you want.
And I, while designing this, I made this tool bar work also in Firefox. It's the same exact tool bar. You can go in here, command b, well they overrode that with bookmarks and they overrode that too. Safari doesn't override any of the defaults so.
( Laughter )
( Applause )
So that's why tool bars are invented. You can come up here and click and italicize and underline. But in Safari, you really don't need the tool bar, you can just use your command keys that you're always used to and everything just works cross browser. So back to slides.
( Applause ) So this tool bar that I designed is going to be available as sample code for the session. ( Applause ) And I believe the version up there right now is a preliminary version that only works in Safari. Last night I just got Firefox working and it only took me a couple hours to get it working. So I'm going to get the new version available and it's going to be up probably soon. So be sure to check back and get the cross browser version.
It's a drop-in library I didn't show you any of the code. That's kind of dense, adding the browser support. It's a lot of code actually. So I'll talk about that later, but it's, this is a drop-in library. You can just include two files. The CSS file and the JavaScript file.
And it'll go in and attach itself to any i frame that has an editable class name on it. So if you just put in any i frames in your code, it'll go in and attach itself on any of those frames. So it'll, it'll respond for focus on any of those.
So I talked about selection in my demo. And selection is difficult. There's a lot of complexities with doing selection in a tree-based structure. And I've brought back my example from earlier showing the HTML nodes. Selection in the webpage is represented with a DOM range. And that's the Document Object Model. Where you have the different nodes of the page, the different elements and a DOM range is represented with a start node and an end node. So there's two nodes somewhere in the tree.
And they have offsets inside of them. So in my example here, my start node is the bold movement node, the bold element and I'm offsetting two characters inside of it. It's not really offset of two characters. It's an offset of characters or elements that are inside of that node. So keep that in mind.
And my end is an offset of some other node that's up higher in the tree. And I'm offsetting from the end End:9. So that's what the selection looks like in the browser. It's just a simple selection. But under the hood it's a DOM range. What's nice about DOM ranges compared to a flat structure, if you make a selection, it's just a number. It's just two number the start and the offset length.
But if you go in and make a change to that text, your numbers are changing behind the scenes. And that's true with a DOM range. The offsets could change. But if you change in the middle, the DOM range is not going to change. It's the same two nodes, it's the same two offsets. But content in the middle has changed. So keep that in mind when you're working with DOM ranges. They could, they can persist through many edits unless you're editing the nodes that are the start and end containers. You're DOM range might not change at all.
So that's selection. How do you get a selection? So the execCommands handle a lot of this for you. Notice in my earlier slides, execCommand didn't do anything with the selection. It just automagically took the selection that the user had and bold or unbolded it. There is no code dealing with the selection. But if you want to do any programmatic work with the selection, here's an example.
I used this earlier. This is the WebKit part of the getting the selection object. There is also other ways to do it for the different browsers as I showed in my other slides. But I'm just going to show the WebKit way. Obviously you would do this in a cross browser way if you really cared about other browsers.
So window.getSelection. That'll get me an object. A lot of you might be familiar with this and you've just seen it get the text. But it's really an object. It's tricky under the hood. JavaScript, when you ask for the text, it gives you the text. Using the two string function on that object.
So if you do an alert, that'll just show you the text selection. People forget it's an object, so there's properties on that object such as the ancestorNode, or the anchorNode and the focusNode, which is the start and the endNode. Funnily named, but it's for cross browsers where other browsers have these same names.
So the anchor node and the offset in that node and the same for the endNode which is the focusNode. And the focusNode is almost the node that you would have if you just had a single insertion point blinking. There would be no anchor node. It would just be the focus node.
So you can also set the selection using the selection object. You get the selection object the same way depending on your browser. This is the WebKit example again. The first thing you'll probably want to do it clear whatever is currently selected. If you start messing with the selection object without clearing it first, it's just going to extend the selection. So keep that in mind.
Here's the first example. You ask the document to create a DOM range. And these are standard DOM calls. If you're not familiar with the DOM, I encourage you to go learn more about the DOM because the DOM is massive. You can spend a lot of time talking just about the DOM. But document has a createRange function that'll give you a new DOM range.
Then you can mess with that DOM range, you can change that DOM range. And there's a selectNode function on that range. And that will select from the start of that one node to the end of the node all of the content in it. And I believe it selects the node in hold too.
That gives you just a range. That doesn't modify the current selection. You just have a DOM range. You can do a lot of other things with DOM ranges in the DOM. But now I want to make that the current selection. So I tell the selection object which is the s variable add this range. That will either extend the range, but we cleared it earlier, but that will extend or set the range to whatever you have passed in.
There's also other ways to make the DOM range. You can specify each start and end node. And the offset into that node. So in this example, I have a paragraph node that I want to offset 10 in and 20 on the other end. And then I add that range just like I did the earlier one. So those two are two different examples of making a DOM range.
So what about saving? I talked earlier, the content editable areas aren't form elements. They don't get sent, the content doesn't get sent when you submit a form. So there's a few ways you can do this. You would use DOM operations. You can get the content of this thing, this editable area by using the innerHTML property. That'll tell you, that'll serialize the DOM nodes for you into HTML. You don't have to worry about serializing and walking the DOM or anything. This'll do it for you. This'll use the engine, the speed of the engine to serialize this DOM for you.
So here's an example. The first one is for an i frame. So I'm getting the content document and then I'm getting the body element. Since the entire document is editable, anything in the body is what I'm really care about. And then I ask the body for the innerHTML and that'll be everything inside the body, serialized in HTML form. The second example is a content editable area. And it's the same concept.
You get your editable area, any div that's on the page. And then ask for its innerHTML. That's everything inside of the div. So what about submitting this? So you got the content, now what do you do with it? So you have a FormElement and Input hidden, so it's not showing up anywhere on the page.
You can change that to text if you want to debug it to see it. But hidden will be a hidden element on the page in your form. And then you have some script that when the form submits, like on your on submit handler for the form, you take the content that you got, find the hidden element that I want to insert this is, and just set the value of that hidden element. That'll put your edited content in the form element.
Any future edits that happen after that won't be saved. But this is a way you can then submit the form. You can also take this content and send it in an XMLHTTPRequest in AJAX, in an AJAX fashion without even leaving the page. So you can have like auto save or things like that, using fancy AJAX technology.
So that's saving. All of this is complicated. I talked about a lot of things. That's just scratching the surface of editing. What if you just want to take this and throw it on your page and use something that's already designed and developed for you? You don't want to spend the time learning all the different browser inconsistencies, all the different support that these browsers have and don't have. So there's a lot of people that have already gone down this route for you and they've designed this JavaScript editing libraries.
And there's just a few up here on screen. TinyMCE, which has helped out a lot in our Open Source community. They've come in and helped fixed bug and file a bunch of bugs to help us really be capable with TinyMCE. Same with FCKeditor and Cute Editor. And there's other if you just Google around, you'll find a lot of these free libraries available. So that's in-page editing using JavaScript. And like I talked about earlier, you Cocoa Heads, now we're going to talk about adding it to your Cocoa application. So.
( Period of silence )
We have a lot of experience with editing in Apple products. And there's also Sanvox from Karelia which has also helped out a lot in the Open Source community. And helped fix and find bugs and really contribute a lot to what's editing for 3.0. We've also improved it a lot for Mail. Mail started using WebKit and WebView for the compose window and preview windows for HTML in Tiger. But now it's all WebKit in Mail. Everything is WebKit for the preview, the edit and it's worked out great for the Mail team.
And they've added the new stationary feature in Leopard that uses ContentEditable areas. Before they were just using DesignMode. Now it's ContentEditable. So these stationeries have pockets of information. And remember what I said about don't sleep through the in-page editing. This is why, because you can use the same content editable, in-page features in your Cocoa application like Mail has done.
( Period of silence )
So to the Cocoa people, a lot of this sounds like NSTextView. Well it is. We started with the API, the NSText for API and added support almost every NSResponder or command, editing related command that you can think of. And that's in both NSTextView and WebView when the WebView is editable.
NSTextView has other things that WebView doesn't have like ligature support, if that's important to you. But WebView goes a lot far beyond that with full HTML support. NSTextView has it with HTML on attributed string, where you can turn HTML into one of these string objects for the text area. But its not full HTML support. And certainly not full CSS support. Which WebView has just because it's, it needs to be a great web browser too. So that's some of the differences between NSTextView and WebView.
So like, like I was talking about earlier, you can use both editing modes, DesignMode, and ContentEditable, just like Mail is doing in Leopard. And selection is still represented with a DOM range. You still can get a DOM range object for the selection, and manipulate and change, using the same API. JavaScript API and the, the Objective-C DOM APIs.
And you still need to use the DOM operations to serialize your content when you want to save or get the information back out and put it, send an e-mail message, save it to disk. You still use the DOM calls. So let's talk about three things about the WebKit editing APIs. How to enable editing for a WebView?
And that's really as simple as this. Set editable, YES. And that turns on design mode essentially for the WebView. Everything is editable. Everything in the document, everything you load is editable from then on. And when you use ContentEditable, you don't want to turn on setEditable. Because then things outside of your ContentEditable areas will still be editable. If you really want to mix non editable areas like in stationary, you just want to use the Content Editable property and not even worry about set editable.
So that was, that's all you need to enable editing for a WebView. That gets you basically everything that NSTextView can do. You can then go in and start typing all the commands that are supported, command b, command i, command u, everything else that you normally do in NSTextView.
But WebView had to go a lot, far beyond that because there's a lot of HTML web technologies it needs to convey through its editing APIs. So WebView has tons of delegates. There's five different delegates I think. And editing is one of the delegates that you can be a delegate of.
And I'm going to go into some of the delegates now, but there's many more methods that you can implement to augment these default behaviors. If you want to do something different when command b is pressed, you can. If you want to go in and manipulate the DOM during one of these operations, you can. And in a lot of the cases, you simply return no to prevent the default behavior.
( Period of silence )
So now let's talk about a few. So shouldBeginEditing, did EndEditing. These are very straightforward things. And you can return node to prevent the editing from completing or starting altogether. ShouldInsertNode, shouldInsertText, shouldDeleteDOMRange. These are all about inserting and deleting things from the WebView. You get these callbacks. And I'm going to have all of these on the slide at the end, so you can write these down. But they're going to disappear as I talk about them.
So like I said earlier, DOM ranges are all about the selection. So this is what's going to happen when you type in text, when you insert and delete things. You're going to get a DOM range. So you're going to need to be very familiar with the DOM range object to work with these callbacks.
And then we have the styling information, all about CSS again. That's how style is represented on the web. So you get a callback, did ApplyStyle, should ApplyStyle and I only have the shoulds up here. These are about the typing style and when someone presses command b, you'll get a callback saying okay, now this range has the bold property on it.
( Period of silence )
This is the very powerful command, the selector you really might be interested in a lot. So I talked about the NSResponder API and that's all about CommandByWelector. So you might be familiar with that when you're overriding things in NSTextView sub class. Well you really don't need the subclass WebView to do that here. Because WebView has nested views and a lot of inner workings that's different than a normal view. We've exposed this normally subclass method to the editing delegate. So you'll get this call before WebKit handles the selector.
So you'll get a call from the bold selector and every, all the other NSResponder selectors. And if you handle it return yes and WebView won't do anything with it. You can do any DOM operations in response to one of these selectors. So that's a very, very powerful editing delegate method that you should know about.
And then there's a few at the end that are just default notifications that we sign you up for. Any object can sign themselves up for these notifications, be an observer of these. Begining editing, did editing, changing the typing style, changing selection. The bottom one is really important if you're tracking the selection. So when the selection changes, you can then ask the WebView what the current selected DOM range is and follow it if you need to.
So here's all of them. There's not, this isn't all of them. But here's all the ones that I talked about. And there's more all documented in the headers. Nothing really new in Leopard, so you don't have to worry about compatibility between Tiger and Leopard. Obviously the editing support is a lot better with the new WebKit and that's also available on Tiger too.
So if you want to require the new WebKit once it's a final version, that would have the better editing support ( Period of silence ) So that's the editing delegate. But there's a few additional methods on WebView that aren't your typical NSTextView APIs. And here's just a few. There's a couple more other than these.
You can get the current editing area at a particular point of a WebView. If you're using ContentEditable there's pockets of editing areas. Some is editable, some is not. And this API will return nil or an empty DOM range if the current point is not an editable area. But if it is an editing area, it'll return the range from start to end, everything that's in that editable area.
So you can tell immediately if the user just clicked for example on one of these editing areas if you want to show your tool bar or show your UI or do whatever you need to. And then there's also ways to get the selected DOM range and set the selected DOM range. And you still ask the document to create a new DOM range for you, just like you do in JavaScript, using the Cocoa API for that.
And you can also get the current typing style and set the current typing style. This is a CSS declaration. And I talked a little bit about this last year and some of the other sessions where you can make a typing style or a CSS style declaration with all the typing style information you want the current user to be typing when, when they actually start inserting characters.
So that's the additional APIs. There's not a lot. Again it's very similar to NSTextView. So if you're using NSTextView now, I recommend if you're interested or need HTML support, just use a WebView. There's no reason to be converting back and forth between attributed strings and HTML. You can use a WebView and get everything that WebKit supports in HTML and CSS.
So that's it for the Cocoa session of the talk. And in summary, Safari and WebKit fully support rich editing now. Editing is very hot and large in this version of Safari.
( Applause )
( Cheering )
Try it on Windows, try it on Mac. It's the same engine. The same editing features are in both. Test, test, test. Test Safari, test WebKit when deploying your new sites. This is critical now that we have a lot more users of Safari. Now that the Windows version is out.
And again, test for functionality. If you're testing for engine features, not browser versions or engine versions if you can avoid it. and for the Cocoa people, if you're really interested in HTML and need HTML output or fully styled areas in your application, editable areas, fully visual that you would normally have to subclass NSTextView and NSLayoutManager and all these other crazy classes, you could use a WebView and simple HTML and CSS to achieve the same thing.
And that's it. We have, the sample code is going to be up, like I said. There's a preliminary version up there now. And I'm going to upload the new version that has the cross browser support. And we have an article, a new article that's been updated about JavaScript Object Detection if you're interested in that.
On the ADC site. We also have a lab on Friday. I encourage you to come if you're still sober and here. ( Laughter ) At 3:30 to come down and talk to us about editing. I'll be there personally. And a lot of my teammates will be there. Where we'll answer any of your questions about the new Safari, the new WebKit, how it works, anything like that.
And just some information about the new version of WebKit. A lot of you have noticed that it replaces the system version of the framework. The beta replaces the currently available system version of the framework. And a lot of people are wondering why we didn't put that into a double clickable version of the new Safari.
Because we didn't want to hold back all of this great new technology, this new editing support from your applications. We certain could have shipped a new version of WebKit that was just for Safari and only Safari. But we want, all that powerful new features in WebKit to be available to all the web, all the application developers out there that are using WebKit. And let us know if there's any bugs or breaks, anything in your application. Just let us know. And if you have any trouble or questions about that, come down to the lab and talk to us.