зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1425574 - Fill the feature gap between Console.jsm and Console API - part 1 - Console.createInstance(), r=smaug
This commit is contained in:
Родитель
08ad867b55
Коммит
d820259403
|
@ -153,6 +153,10 @@ DOMInterfaces = {
|
|||
'nativeType': 'mozilla::dom::Console',
|
||||
},
|
||||
|
||||
'ConsoleInstance': {
|
||||
'implicitJSContext': ['clear', 'count', 'groupEnd', 'time', 'timeEnd'],
|
||||
},
|
||||
|
||||
'ConvolverNode': {
|
||||
'implicitJSContext': [ 'buffer' ],
|
||||
},
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/Console.h"
|
||||
#include "mozilla/dom/ConsoleInstance.h"
|
||||
#include "mozilla/dom/ConsoleBinding.h"
|
||||
|
||||
#include "mozilla/dom/BlobBinding.h"
|
||||
|
@ -950,13 +951,6 @@ METHOD(Debug, "debug")
|
|||
METHOD(Table, "table")
|
||||
METHOD(Trace, "trace")
|
||||
|
||||
/* static */ void
|
||||
Console::Clear(const GlobalObject& aGlobal)
|
||||
{
|
||||
const Sequence<JS::Value> data;
|
||||
Method(aGlobal, MethodClear, NS_LITERAL_STRING("clear"), data);
|
||||
}
|
||||
|
||||
// Displays an interactive listing of all the properties of an object.
|
||||
METHOD(Dir, "dir");
|
||||
METHOD(Dirxml, "dirxml");
|
||||
|
@ -964,6 +958,15 @@ METHOD(Dirxml, "dirxml");
|
|||
METHOD(Group, "group")
|
||||
METHOD(GroupCollapsed, "groupCollapsed")
|
||||
|
||||
#undef METHOD
|
||||
|
||||
/* static */ void
|
||||
Console::Clear(const GlobalObject& aGlobal)
|
||||
{
|
||||
const Sequence<JS::Value> data;
|
||||
Method(aGlobal, MethodClear, NS_LITERAL_STRING("clear"), data);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
Console::GroupEnd(const GlobalObject& aGlobal)
|
||||
{
|
||||
|
@ -987,15 +990,27 @@ Console::TimeEnd(const GlobalObject& aGlobal, const nsAString& aLabel)
|
|||
Console::StringMethod(const GlobalObject& aGlobal, const nsAString& aLabel,
|
||||
MethodName aMethodName, const nsAString& aMethodString)
|
||||
{
|
||||
JSContext* cx = aGlobal.Context();
|
||||
RefPtr<Console> console = GetConsole(aGlobal);
|
||||
if (!console) {
|
||||
return;
|
||||
}
|
||||
|
||||
ClearException ce(cx);
|
||||
console->StringMethodInternal(aGlobal.Context(), aLabel, aMethodName,
|
||||
aMethodString);
|
||||
}
|
||||
|
||||
void
|
||||
Console::StringMethodInternal(JSContext* aCx, const nsAString& aLabel,
|
||||
MethodName aMethodName,
|
||||
const nsAString& aMethodString)
|
||||
{
|
||||
ClearException ce(aCx);
|
||||
|
||||
Sequence<JS::Value> data;
|
||||
SequenceRooter<JS::Value> rooter(cx, &data);
|
||||
SequenceRooter<JS::Value> rooter(aCx, &data);
|
||||
|
||||
JS::Rooted<JS::Value> value(cx);
|
||||
if (!dom::ToJSValue(cx, aLabel, &value)) {
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
if (!dom::ToJSValue(aCx, aLabel, &value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1003,7 +1018,7 @@ Console::StringMethod(const GlobalObject& aGlobal, const nsAString& aLabel,
|
|||
return;
|
||||
}
|
||||
|
||||
Method(aGlobal, aMethodName, aMethodString, data);
|
||||
MethodInternal(aCx, aMethodName, aMethodString, data);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
|
@ -2537,5 +2552,13 @@ Console::MonotonicTimer(JSContext* aCx, MethodName aMethodName,
|
|||
return true;
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<ConsoleInstance>
|
||||
Console::CreateInstance(const GlobalObject& aGlobal,
|
||||
const ConsoleInstanceOptions& aOptions)
|
||||
{
|
||||
RefPtr<ConsoleInstance> console = new ConsoleInstance(aOptions);
|
||||
return console.forget();
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -27,9 +27,11 @@ namespace dom {
|
|||
|
||||
class AnyCallback;
|
||||
class ConsoleCallData;
|
||||
class ConsoleInstance;
|
||||
class ConsoleRunnable;
|
||||
class ConsoleCallDataRunnable;
|
||||
class ConsoleProfileRunnable;
|
||||
struct ConsoleInstanceOptions;
|
||||
struct ConsoleTimerError;
|
||||
struct ConsoleStackEntry;
|
||||
|
||||
|
@ -114,6 +116,10 @@ public:
|
|||
static void
|
||||
Clear(const GlobalObject& aGlobal);
|
||||
|
||||
static already_AddRefed<ConsoleInstance>
|
||||
CreateInstance(const GlobalObject& aGlobal,
|
||||
const ConsoleInstanceOptions& aOptions);
|
||||
|
||||
void
|
||||
ClearStorage();
|
||||
|
||||
|
@ -183,6 +189,10 @@ private:
|
|||
StringMethod(const GlobalObject& aGlobal, const nsAString& aLabel,
|
||||
MethodName aMethodName, const nsAString& aMethodString);
|
||||
|
||||
void
|
||||
StringMethodInternal(JSContext* aCx, const nsAString& aLabel,
|
||||
MethodName aMethodName, const nsAString& aMethodString);
|
||||
|
||||
// This method must receive aCx and aArguments in the same JSCompartment.
|
||||
void
|
||||
ProcessCallData(JSContext* aCx,
|
||||
|
@ -417,6 +427,7 @@ private:
|
|||
mozilla::TimeStamp mCreationTimeStamp;
|
||||
|
||||
friend class ConsoleCallData;
|
||||
friend class ConsoleInstance;
|
||||
friend class ConsoleRunnable;
|
||||
friend class ConsoleCallDataRunnable;
|
||||
friend class ConsoleProfileRunnable;
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/ConsoleInstance.h"
|
||||
#include "mozilla/dom/ConsoleBinding.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ConsoleInstance, mConsole)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(ConsoleInstance)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(ConsoleInstance)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ConsoleInstance)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
ConsoleInstance::ConsoleInstance(const ConsoleInstanceOptions& aOptions)
|
||||
: mConsole(new Console(nullptr))
|
||||
{}
|
||||
|
||||
ConsoleInstance::~ConsoleInstance()
|
||||
{}
|
||||
|
||||
JSObject*
|
||||
ConsoleInstance::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
||||
{
|
||||
return ConsoleInstanceBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
#define METHOD(name, string) \
|
||||
void \
|
||||
ConsoleInstance::name(JSContext* aCx, const Sequence<JS::Value>& aData) \
|
||||
{ \
|
||||
mConsole->MethodInternal(aCx, Console::Method##name, \
|
||||
NS_LITERAL_STRING(string), aData); \
|
||||
}
|
||||
|
||||
METHOD(Log, "log")
|
||||
METHOD(Info, "info")
|
||||
METHOD(Warn, "warn")
|
||||
METHOD(Error, "error")
|
||||
METHOD(Exception, "exception")
|
||||
METHOD(Debug, "debug")
|
||||
METHOD(Table, "table")
|
||||
METHOD(Trace, "trace")
|
||||
METHOD(Dir, "dir");
|
||||
METHOD(Dirxml, "dirxml");
|
||||
METHOD(Group, "group")
|
||||
METHOD(GroupCollapsed, "groupCollapsed")
|
||||
|
||||
#undef METHOD
|
||||
|
||||
void
|
||||
ConsoleInstance::GroupEnd(JSContext* aCx)
|
||||
{
|
||||
const Sequence<JS::Value> data;
|
||||
mConsole->MethodInternal(aCx, Console::MethodGroupEnd,
|
||||
NS_LITERAL_STRING("groupEnd"), data);
|
||||
}
|
||||
|
||||
void
|
||||
ConsoleInstance::Time(JSContext* aCx, const nsAString& aLabel)
|
||||
{
|
||||
mConsole->StringMethodInternal(aCx, aLabel, Console::MethodTime,
|
||||
NS_LITERAL_STRING("time"));
|
||||
}
|
||||
|
||||
void
|
||||
ConsoleInstance::TimeEnd(JSContext* aCx, const nsAString& aLabel)
|
||||
{
|
||||
mConsole->StringMethodInternal(aCx, aLabel, Console::MethodTimeEnd,
|
||||
NS_LITERAL_STRING("timeEnd"));
|
||||
}
|
||||
|
||||
void
|
||||
ConsoleInstance::TimeStamp(JSContext* aCx, const JS::Handle<JS::Value> aData)
|
||||
{
|
||||
ClearException ce(aCx);
|
||||
|
||||
Sequence<JS::Value> data;
|
||||
SequenceRooter<JS::Value> rooter(aCx, &data);
|
||||
|
||||
if (aData.isString() && !data.AppendElement(aData, fallible)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mConsole->MethodInternal(aCx, Console::MethodTimeStamp,
|
||||
NS_LITERAL_STRING("timeStamp"), data);
|
||||
}
|
||||
|
||||
void
|
||||
ConsoleInstance::Profile(JSContext* aCx, const Sequence<JS::Value>& aData)
|
||||
{
|
||||
mConsole->ProfileMethodInternal(aCx, NS_LITERAL_STRING("profile"), aData);
|
||||
}
|
||||
|
||||
void
|
||||
ConsoleInstance::ProfileEnd(JSContext* aCx, const Sequence<JS::Value>& aData)
|
||||
{
|
||||
mConsole->ProfileMethodInternal(aCx, NS_LITERAL_STRING("profileEnd"), aData);
|
||||
}
|
||||
|
||||
void
|
||||
ConsoleInstance::Assert(JSContext* aCx, bool aCondition,
|
||||
const Sequence<JS::Value>& aData)
|
||||
{
|
||||
if (!aCondition) {
|
||||
mConsole->MethodInternal(aCx, Console::MethodAssert,
|
||||
NS_LITERAL_STRING("assert"), aData);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ConsoleInstance::Count(JSContext* aCx, const nsAString& aLabel)
|
||||
{
|
||||
mConsole->StringMethodInternal(aCx, aLabel, Console::MethodCount,
|
||||
NS_LITERAL_STRING("count"));
|
||||
}
|
||||
|
||||
void
|
||||
ConsoleInstance::Clear(JSContext* aCx)
|
||||
{
|
||||
const Sequence<JS::Value> data;
|
||||
mConsole->MethodInternal(aCx, Console::MethodClear,
|
||||
NS_LITERAL_STRING("clear"), data);
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,106 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_ConsoleInstance_h
|
||||
#define mozilla_dom_ConsoleInstance_h
|
||||
|
||||
#include "mozilla/dom/Console.h"
|
||||
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class ConsoleInstance final : public nsISupports
|
||||
, public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ConsoleInstance)
|
||||
|
||||
explicit ConsoleInstance(const ConsoleInstanceOptions& aOptions);
|
||||
|
||||
// WebIDL methods
|
||||
JSObject*
|
||||
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
nsPIDOMWindowInner* GetParentObject() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
Log(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
Info(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
Warn(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
Error(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
Exception(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
Debug(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
Table(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
Trace(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
Dir(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
Dirxml(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
Group(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
GroupCollapsed(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
GroupEnd(JSContext* aCx);
|
||||
|
||||
void
|
||||
Time(JSContext* aCx, const nsAString& aLabel);
|
||||
|
||||
void
|
||||
TimeEnd(JSContext* aCx, const nsAString& aLabel);
|
||||
|
||||
void
|
||||
TimeStamp(JSContext* aCx, const JS::Handle<JS::Value> aData);
|
||||
|
||||
void
|
||||
Profile(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
ProfileEnd(JSContext* aCx, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
Assert(JSContext* aCx, bool aCondition, const Sequence<JS::Value>& aData);
|
||||
|
||||
void
|
||||
Count(JSContext* aCx, const nsAString& aLabel);
|
||||
|
||||
void
|
||||
Clear(JSContext* aCx);
|
||||
|
||||
private:
|
||||
~ConsoleInstance();
|
||||
|
||||
RefPtr<Console> mConsole;
|
||||
};
|
||||
|
||||
} // dom namespace
|
||||
} // mozilla namespace
|
||||
|
||||
#endif // mozilla_dom_ConsoleInstance_h
|
|
@ -23,10 +23,12 @@ EXPORTS.mozilla += [
|
|||
|
||||
EXPORTS.mozilla.dom += [
|
||||
'Console.h',
|
||||
'ConsoleInstance.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'Console.cpp',
|
||||
'ConsoleInstance.cpp',
|
||||
'ConsoleReportCollector.cpp',
|
||||
]
|
||||
|
||||
|
|
|
@ -7,5 +7,6 @@ this.EXPORTED_SYMBOLS = [ "ConsoleTest" ];
|
|||
this.ConsoleTest = {
|
||||
go: function() {
|
||||
console.log("Hello world!");
|
||||
console.createInstance().log("Hello world!");
|
||||
}
|
||||
};
|
||||
|
|
|
@ -22,6 +22,8 @@ function consoleListener() {
|
|||
}
|
||||
|
||||
consoleListener.prototype = {
|
||||
count: 0,
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
if (aTopic == "console-api-log-event") {
|
||||
var obj = aSubject.wrappedJSObject;
|
||||
|
@ -29,8 +31,12 @@ consoleListener.prototype = {
|
|||
is(obj.ID, "jsm", "ID and InnerID are correctly set.");
|
||||
is (obj.arguments[0], "Hello world!", "Message matches");
|
||||
|
||||
SpecialPowers.removeObserver(this, "console-api-log-event");
|
||||
SimpleTest.finish();
|
||||
// We want to see 2 messages, the first is generated by console.log,
|
||||
// the second one from createInstance().log();
|
||||
if (++this.count == 2) {
|
||||
SpecialPowers.removeObserver(this, "console-api-log-event");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,10 @@
|
|||
ClassString="Console",
|
||||
ProtoObjectHack]
|
||||
namespace console {
|
||||
|
||||
// NOTE: if you touch this namespace, remember to update the ConsoleInstance
|
||||
// interface as well!
|
||||
|
||||
// Logging
|
||||
void assert(optional boolean condition = false, any... data);
|
||||
void clear();
|
||||
|
@ -45,6 +49,9 @@ namespace console {
|
|||
|
||||
[ChromeOnly]
|
||||
const boolean IS_NATIVE_CONSOLE = true;
|
||||
|
||||
[ChromeOnly, NewObject]
|
||||
ConsoleInstance createInstance(optional ConsoleInstanceOptions options);
|
||||
};
|
||||
|
||||
// This is used to propagate console events to the observers.
|
||||
|
@ -109,3 +116,43 @@ dictionary ConsoleCounter {
|
|||
dictionary ConsoleCounterError {
|
||||
DOMString error = "maxCountersExceeded";
|
||||
};
|
||||
|
||||
[ChromeOnly,
|
||||
Exposed=(Window,Worker,WorkerDebugger,Worklet,System)]
|
||||
// This is basically a copy of the console namespace.
|
||||
interface ConsoleInstance {
|
||||
// Logging
|
||||
void assert(optional boolean condition = false, any... data);
|
||||
void clear();
|
||||
void count(optional DOMString label = "default");
|
||||
void debug(any... data);
|
||||
void error(any... data);
|
||||
void info(any... data);
|
||||
void log(any... data);
|
||||
void table(any... data); // FIXME: The spec is still unclear about this.
|
||||
void trace(any... data);
|
||||
void warn(any... data);
|
||||
void dir(any... data); // FIXME: This doesn't follow the spec yet.
|
||||
void dirxml(any... data);
|
||||
|
||||
// Grouping
|
||||
void group(any... data);
|
||||
void groupCollapsed(any... data);
|
||||
void groupEnd();
|
||||
|
||||
// Timing
|
||||
void time(optional DOMString label = "default");
|
||||
void timeEnd(optional DOMString label = "default");
|
||||
|
||||
// Mozilla only or Webcompat methods
|
||||
|
||||
void _exception(any... data);
|
||||
void timeStamp(optional any data);
|
||||
|
||||
void profile(any... data);
|
||||
void profileEnd(any... data);
|
||||
};
|
||||
|
||||
dictionary ConsoleInstanceOptions {
|
||||
// TODO
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче