views:

824

answers:

2

I'm working on a OS X program where the user does some light WYSIWYG HTML editing in a WebView. Being new to programming with Cocoa and WebKit, I have absolutely no idea how to get selected text from a WebView - the intention being to take what the user selected, add HTML code (like div's or span's) around the text, and replace the selected text with the modified code. How can this be accomplished?

I'm currently programming this project with MacRuby, but I'd appreciate help from Objective-C programmers as well. Thank you!

A: 

UIWebView lets you run arbitrary JavaScript:

[webview stringByEvaluatingJavaScriptFromString:@"document.getElementsByTagName('html')[0].innerHTML"]
Marcelo Cantos
So does WebView. http://developer.apple.com/mac/library/documentation/Cocoa/Reference/WebKit/Classes/WebView_Class/
Peter Hosey
If you want to use JavaScript in the `WebView` you're much better off getting a pointer to the the `WebView`'s `windowScriptObject` property, which returns a `WebScriptObject` which you can use to evaluate JavaScript. The iPhone SDK's UIWebView is very limited and requires the use of `-stringByEvaluatingJavaScriptFromString:` which is more of a hack than anything else. `WebView` on Mac OS X is much more powerful.
Rob Keniger
+1  A: 

You can ask for the WebView's -selectedDOMRange and you'll get a DOMRange object back. You can use this object to find out what is selected. DOMRange, like all WebKit DOM objects, is an Objective-C representation of a standard W3C DOMRange object, see DOMRange.h for what methods/properties it supports.

You can then replace the current selection using the -replaceSelectionWithMarkupString:, -replaceSelectionWithText: or -replaceSelectionWithNode: methods of WebView.

Rob Keniger
I hate to ask something that probably has an answer obvious to everyone else, but if I wanted to replace the markup with <somemarkup> + the selected markup + </somemarkup>, how would I do that? Those all seem to indicate to me that the selected markup will be destroyed.
Jim C
You need to use the `DOMRange` object that is passed back to you and use its methods/properties to inspect the content that is selected. An HTML document is not just a string, the DOM may have been modified dynamically so you must do the work to ensure that you are replacing the selected content with valid markup. WebKit defines the `-markupString` method of DOMRange, but unfortunately this will probably not give you what you need. You should probably construct a valid DOMNode structure and insert that, possibly with a different range to the one you received from the WebView.
Rob Keniger