Bug 25607

Summary: Need a way to catch (and cancel?) any execCommand. Maybe document.onexeccommand = ?
Product: WebKit Reporter: Eric Seidel (no email) <eric>
Component: HTML EditingAssignee: Nobody <webkit-unassigned>
Status: NEW ---    
Severity: Normal CC: alex, ap, ayg, jparent, michael.vm, morrita, morrita, rniwa, slightlyoff
Priority: P2 Keywords: GoogleBug
Version: 528+ (Nightly build)   
Hardware: Mac   
OS: OS X 10.5   
Bug Depends on: 25606, 25604    
Bug Blocks:    

Description Eric Seidel (no email) 2009-05-06 22:27:06 PDT
Need a way to catch (and cancel?) any execCommand.  Maybe document.onexeccommand = ?

One of the HTML editing teams here @ Google is looking for a way to catch any exec command before execution.  They may not actually need a hook that broad, but they have a number of use cases to support this need:

Ability to catch bold, italic, undo, redo are 4 examples which come to mind.

In general they need to catch all DOM modifications before they happen so that they can update the JS editing library's internal state.  Ideally they want to cancel these dom modifications as well.  Having a hook for onexeccommand would bring them close to this working.
Comment 1 Alexey Proskuryakov 2009-11-21 13:03:12 PST
I'm not sure what this bug is asking about. Do they want to catch execCommand, or any "command" that's executed internally due to a user action?

In the former case, a simpler solution may be to not call execCommand, in the first place!
Comment 2 Julie Parent 2009-11-21 14:08:17 PST
I think this was talking about internal cases, not calling execCommand directly.  Specifically, cases where WebKit takes a default editing action inside a contentEditable/designMode region, and there is no way for an app to override.

Examples: selecting "undo", "redo", "copy", "paste", etc from the right click menu or toolbar or the default behavior for "bold", "italic", etc whenever inside a contentEditable region and the user hits ctrl/cmd + b/i/u.

Some of these (paste, copy) have other events that can be listened to, but the others do not.
Comment 3 Ojan Vafai 2009-12-18 14:16:20 PST
One possibility here would be to fire (cancelable?) "input" events as per bug 26526. The execCommand could be the value of the proposed "type" property on the event.
Comment 4 Ryosuke Niwa 2010-07-28 19:09:46 PDT
Alex proposed an alternative approach of exposing each command of execCommand as a method of document, window, etc... and make it replaceable by JavaScript, and have all editing commands such as bolding initiated by user go through that API.

So for example, you can override the bolding operation as follows:

var b = document.execCommand.bold;
document.execCommand.bold = function (range, showDefaultUI, value) {
  if (...) {...}// take care of my stuff here
  return b(range, showDefaultUI, value); // call the original for other cases
}
Comment 5 Alex Russell 2010-07-28 19:20:58 PDT
(In reply to comment #4)
> Alex proposed an alternative approach of exposing each command of execCommand as a method of document, window, etc... and make it replaceable by JavaScript, and have all editing commands such as bolding initiated by user go through that API.
> 
> So for example, you can override the bolding operation as follows:
> 
> var b = document.execCommand.bold;
> document.execCommand.bold = function (range, showDefaultUI, value) {
>   if (...) {...}// take care of my stuff here
>   return b(range, showDefaultUI, value); // call the original for other cases
> }

I'd actually suggested a new map, something like "document.commands" that would be where the existing and new commands could be listed and replaced. E.g.:

var c = document.commands;
var b = c.bold;
c.bold = function(range, defaultUI, value) {
   // call original or do your own processing here
   return b.apply(this, arguments); // no-op
};
Comment 6 Alexey Proskuryakov 2010-08-02 03:09:03 PDT
The hardest part here would be to specify the feature in a way that can be explained to developers, or implemented by other browsers. There are many ways to perform an action, and actions are different between platforms.

As just one example, invoking a service in Mac OS X is very much like making a copy. Should document.commands.copy affect what text Mac OS X services see, or even cancel them?

Another example: text can be made bold by "paste style" command (we don't have it in Safari, but other apps that use WebKit may have it), or programmatically by an input method. Should document.commands.bold catch that?

It would be a very poor web app UI if it could do magic for Cmd+B and "Bold" item in application menu, but fail on trickier ways to do the same.