Closed Bug 578353 Opened 14 years ago Closed 14 years ago

Create IDL for global console service

Categories

(DevTools :: General, defect)

x86
All
defect
Not set
normal

Tracking

(blocking2.0 betaN+)

RESOLVED DUPLICATE of bug 568629
Tracking Status
blocking2.0 --- betaN+

People

(Reporter: ddahl, Assigned: ddahl)

Details

(Whiteboard: [patches in bug 568629])

jst asked me to create an idl that specifies what to implement in a C++ console service
Blocks: 529086
OS: Linux → All
I think we will need a very similar interface to the existing nsIConsoleService:

nsIGlobalConsoleService: the service that is always running, which is callable from any contentWindow attached to contentWindow.console,  with the following interface:

{

  void info(in nsIVariant aMessage)

  void log(in nsIVariant aMessage);

  void warn(in nsIVariant aMessage);

  void error(in nsIVariant aMessage);

  void registerListener(in nsIGlobalConsoleListener aListener);

  void unregisterListener(in nsIGlobalConsoleListener aListener);

}

nsIGlobalConsoleListener:

{

  void observe(in nsIGlobalConsoleMessage aMessage);
 
}

nsIGlobalConsoleMessage:

{
  const PRUInt32 TYPE_JS_ERR = 1;
  const PRUInt32 TYPE_CSS_PARSE_ERR = 2;
  const PRUInt32 TYPE_JS_STRICT_WARN = 3;

  const PRUInt32 MESSAGE_ORIGIN_CHROME = 1;
  const PRUInt32 MESSAGE_ORIGIN_CONTENT = 2;

  nsIWeakReference contentWindowReference;
  AString message;
  PRUInt32 type;

}



The only thing not explicit in this design is how this service would allow something like the HeadsUpDisplay or Firebug can replace the global window.console with itself.
Assignee: nobody → ddahl
Blocks: lazy-console
So would there be no storage of messages? You would only be able to see these messages if you've got a console actively open and listening, unlike the current JS console, which fetches back messages and is able to show you messages that occurred before opening the console?

I think that is a better idea. The new console service would just be a pipe with ephemeral data flowing through it. If anyone's actually interested in the way the current JS Console works, you would create another service that registers itself at startup as a listener and remains registered throughout the lifetime of the application, and it would manage its own backlog. E.g., it would just have a message queue (of finite-length, if desired), and you don't run into the same kinds of issues you get with the current console service, like, when is it polite to call reset?
(In reply to comment #2)
> So would there be no storage of messages? You would only be able to see these
> messages if you've got a console actively open and listening, unlike the
> current JS console, which fetches back messages and is able to show you
> messages that occurred before opening the console?

This is just a start, and I forgot all about this. I have a storage module in the web console we are building in bug 529086

The storage is also a tricky affair, as we really should keep messages for a minute or two (time based, instead of # of messages), indexed on the window.ID

Again, the simpler the better as this is really just a "catch all" until you invoke your console of choice, and it should provide the observer interface to be able to tell where errors originate.
The current console service, though, doesn't have any notion of a message that's logged versus one which is an error, and I think that's the right approach.

Whether a message is an error or a warning or info is determined by the message itself. We should do this here, too. For example, all messages go through the current service through the logMessage method. Whether it's an error or not depends on whether the message can be QIed by the JS console into a known error type, like nsIScriptError. The current service does provide a convenience method, logStringMessage. I think the new console service should be similar in this regard.

There would be one primary logging method, which takes a console message, and some convenience methods which just set the appropriate severity of the message.

(In reply to comment #1)
> nsIGlobalConsoleMessage:
> 
> {
>   const PRUInt32 TYPE_JS_ERR = 1;
>   const PRUInt32 TYPE_CSS_PARSE_ERR = 2;
>   const PRUInt32 TYPE_JS_STRICT_WARN = 3;
...
>   PRUInt32 type;

This isn't very friendly to other error types (e.g., extension's assertions and other roll-your-own errors). Wouldn't this result in similar things to the way CSS errors today masquerade as nsIScriptErrors? Instead, why not generic UNKNOWN/INFO/WARN/ERROR consts, and doing the JS/CSS discrimination by instanceofing or QIing a more specific message interface, like (a revamped) nsIScriptError and (a newly-formalized, more appropriate) nsICSSParsingError. Ideally, that's how the current console should be doing things already.

> The only thing not explicit in this design is how this service would allow
> something like the HeadsUpDisplay or Firebug can replace the global
> window.console with itself.

That's just a matter of overlays and those things using the new service for their own consoles, instead of rolling their own, isn't it?

Firebug has its own, special-purpose messages, right? It looks like it: <http://www.softwareishard.com/blog/firebug/tabular-logs-in-firebug/> Instead of, uh, whatever approach Firebug is taking today, they'd craft their own, special-purpose, possibly not-even-formalized-by-IDL message types that nonetheless derive from nsIGlobalConsoleMessage, and pass those through the new console service.
(In reply to comment #3)
> (In reply to comment #2)
> > So would there be no storage of messages? You would only be able to see these
> > messages if you've got a console actively open and listening, unlike the
> > current JS console, which fetches back messages and is able to show you
> > messages that occurred before opening the console?
> 
> This is just a start, and I forgot all about this. I have a storage module in
> the web console we are building in bug 529086
> 
> The storage is also a tricky affair, as we really should keep messages for a
> minute or two (time based, instead of # of messages), indexed on the window.ID

No, no; I was in agreement there. Why not take the easier route and just not even worry about retaining messages? If anyone's really interested in doing that, like if someone wanted to set out to reimplement the current JS Console on top of the new service, it's their job to register permanent listeners and maintain their own backlog.
(In reply to comment #5)
> No, no; I was in agreement there. Why not take the easier route and just not
> even worry about retaining messages? If anyone's really interested in doing
> that, like if someone wanted to set out to reimplement the current JS Console
> on top of the new service, it's their job to register permanent listeners and
> maintain their own backlog.

We are doing exactly that (replacing the JS error console), not as a service, but a singleton that does not know anything about the current JS context until manually invoked. After which, we have a storage module to keep a rolling, truncated log. This new service will exist to feed the web console with any previous errors that it does not know about. Once the web console is invoked it only cares about messages that emanate from the current tab. 

So, it would be smart to keep a minute or two of messages available in the globalConsoleService to dump to the web console or firebug when invoked. The biggest usability issue is just this - where we have no idea what "just happened".

I originally wrote the "HeadsUpDisplay" as a JS XPCOM service, but in review it was changed to a .jsm "Singleton" so it would not affect startup performance.

So, I imagine the nsIGlobalConsoleService would also have:

{
  /**
   * Gets all recent messages that emanated from window specified by windowId
   * @param PRUInt32 aWindowId
   * @returns nsIVariant
   */
  nsIVariant getMessages(in wstring aWindowId);
}


Also, each message needs a timestamp as well.
(In reply to comment #1)
>
> {
> 
>   void info(in nsIVariant aMessage)
> 
>   void log(in nsIVariant aMessage);
> 
>   void warn(in nsIVariant aMessage);
> 
>   void error(in nsIVariant aMessage);
> 
>   void registerListener(in nsIGlobalConsoleListener aListener);
> 
>   void unregisterListener(in nsIGlobalConsoleListener aListener);
> 
> }

Note that console.log/info/warn/error can take multiple arguments like:

    console.log("Hello", "World");

The draft seems to handle only the first argument.
(In reply to comment #7)
> Note that console.log/info/warn/error can take multiple arguments like:
> 
>     console.log("Hello", "World");
> 
> The draft seems to handle only the first argument.

I spoke with jst about this, but I was not sure if we eventually want to support multiple args in the dev console, should this also support it, or can XPCOM deal with them via a JS "arguments" approach?

I personally have never used multiple args, but I may be in the minority.
(In reply to comment #7)
> Note that console.log/info/warn/error can take multiple arguments like:
> 
>     console.log("Hello", "World");
> 
> The draft seems to handle only the first argument.

When you say those APIs take multiple arguments are you saying that implementations other than Firebug (i.e. WebKit's console etc?) supports that, or are you talking purely about what Firebug supports here?

FWIW, I think what we need here is a *simple* console "broadcasting" service that does one thing and only one thing, and that is to implement the minimal API (ideally no magic multiple argument handling, crippled printf() formatting, single argument) that just exists in the DOM and calls into any and/or all other console implementations. It is then up to those console implementations to timestamp, store, do whatever they want, with the received messages. In the case of Firebug it is free to override any of the methods with its own implementations (like it does now, except instead of providing the whole console object it can just change the one that's provided), and once it's done processing its own messages it is up to Firebug to call into the standard console so that other consumers receive the messages as well.

My thinking so far is to have console observers (i.e. Firebug and ddahl's console, and whatever else) register themselves as a XPCOM category and the broadcaster simply enumerates all registered console implementations and forwards the message to all of them.
(In reply to comment #9)
> (In reply to comment #7)
> > Note that console.log/info/warn/error can take multiple arguments like:
> > 
> >     console.log("Hello", "World");
> > 
> > The draft seems to handle only the first argument.
> 
> When you say those APIs take multiple arguments are you saying that
> implementations other than Firebug (i.e. WebKit's console etc?) supports that,
> or are you talking purely about what Firebug supports here?

Firebug as well as WebKit's console handle multiple arguments passed to console.log/info/warn/error.
(In reply to comment #9)
> (In reply to comment #7)
> > Note that console.log/info/warn/error can take multiple arguments like:
> > 
> >     console.log("Hello", "World");
> > 
> > The draft seems to handle only the first argument.
> 
> When you say those APIs take multiple arguments are you saying that
> implementations other than Firebug (i.e. WebKit's console etc?) supports that,
> or are you talking purely about what Firebug supports here?

yeah, they all support multiple args as Julian mentions below.

> FWIW, I think what we need here is a *simple* console "broadcasting" service
> that does one thing and only one thing, and that is to implement the minimal
> API (ideally no magic multiple argument handling, crippled printf() formatting,
> single argument) that just exists in the DOM and calls into any and/or all
> other console implementations. It is then up to those console implementations
> to timestamp, store, do whatever they want, with the received messages. In the
> case of Firebug it is free to override any of the methods with its own
> implementations (like it does now, except instead of providing the whole
> console object it can just change the one that's provided), and once it's done
> processing its own messages it is up to Firebug to call into the standard
> console so that other consumers receive the messages as well.

I'm all for the minimalist approach to keep this bug as simple as possible. I do think we need to support multiple arguments though so existing web development code works without having to completely rewrite it.

How much extra effort does dealing with multiple arguments add to this?

> My thinking so far is to have console observers (i.e. Firebug and ddahl's
> console, and whatever else) register themselves as a XPCOM category and the
> broadcaster simply enumerates all registered console implementations and
> forwards the message to all of them.

+1 to this!
blocking2.0: --- → betaN+
Whiteboard: [kd4b4]
Whiteboard: [kd4b4] → [kd4b5]
Whiteboard: [kd4b5] → [kd4b6]
Severity: normal → blocker
Reprioritizing bugs. You can filter the mail on the word TEABAGS.
Severity: blocker → normal
Blocks: devtools4b7
Whiteboard: [kd4b6] → [kd4b6] [patches in bug 568629]
Blocks: devtools4b8
No longer blocks: devtools4b7
Whiteboard: [kd4b6] [patches in bug 568629] → [patches in bug 568629]
Status: NEW → ASSIGNED
Does this still block?
Yes, and is close to landing. patches in bug 568629
Don't think there's much benefit to tracking this separately now, the patch in bug 568629 covers this.
No longer blocks: 529086, lazy-console, devtools4b8
Status: ASSIGNED → RESOLVED
Closed: 14 years ago
Keywords: dev-doc-needed
Resolution: --- → DUPLICATE
Product: Firefox → DevTools
You need to log in before you can comment on or make changes to this bug.