michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef mozilla_dom_Console_h michael@0: #define mozilla_dom_Console_h michael@0: michael@0: #include "mozilla/dom/BindingDeclarations.h" michael@0: #include "mozilla/dom/UnionConversions.h" michael@0: #include "mozilla/ErrorResult.h" michael@0: #include "nsCycleCollectionParticipant.h" michael@0: #include "nsDataHashtable.h" michael@0: #include "nsHashKeys.h" michael@0: #include "nsIObserver.h" michael@0: #include "nsITimer.h" michael@0: #include "nsWrapperCache.h" michael@0: michael@0: class nsIConsoleAPIStorage; michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: michael@0: class ConsoleCallData; michael@0: class ConsoleStackEntry; michael@0: michael@0: class Console MOZ_FINAL : public nsITimerCallback michael@0: , public nsIObserver michael@0: , public nsWrapperCache michael@0: { michael@0: public: michael@0: NS_DECL_CYCLE_COLLECTING_ISUPPORTS michael@0: NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(Console, michael@0: nsITimerCallback) michael@0: NS_DECL_NSITIMERCALLBACK michael@0: NS_DECL_NSIOBSERVER michael@0: michael@0: Console(nsPIDOMWindow* aWindow); michael@0: ~Console(); michael@0: michael@0: // WebIDL methods michael@0: nsISupports* GetParentObject() const michael@0: { michael@0: return mWindow; michael@0: } michael@0: michael@0: virtual JSObject* michael@0: WrapObject(JSContext* aCx) MOZ_OVERRIDE; michael@0: michael@0: void michael@0: Log(JSContext* aCx, const Sequence& aData); michael@0: michael@0: void michael@0: Info(JSContext* aCx, const Sequence& aData); michael@0: michael@0: void michael@0: Warn(JSContext* aCx, const Sequence& aData); michael@0: michael@0: void michael@0: Error(JSContext* aCx, const Sequence& aData); michael@0: michael@0: void michael@0: Exception(JSContext* aCx, const Sequence& aData); michael@0: michael@0: void michael@0: Debug(JSContext* aCx, const Sequence& aData); michael@0: michael@0: void michael@0: Trace(JSContext* aCx); michael@0: michael@0: void michael@0: Dir(JSContext* aCx, const Sequence& aData); michael@0: michael@0: void michael@0: Group(JSContext* aCx, const Sequence& aData); michael@0: michael@0: void michael@0: GroupCollapsed(JSContext* aCx, const Sequence& aData); michael@0: michael@0: void michael@0: GroupEnd(JSContext* aCx, const Sequence& aData); michael@0: michael@0: void michael@0: Time(JSContext* aCx, const JS::Handle aTime); michael@0: michael@0: void michael@0: TimeEnd(JSContext* aCx, const JS::Handle aTime); michael@0: michael@0: void michael@0: Profile(JSContext* aCx, const Sequence& aData); michael@0: michael@0: void michael@0: ProfileEnd(JSContext* aCx, const Sequence& aData); michael@0: michael@0: void michael@0: Assert(JSContext* aCx, bool aCondition, const Sequence& aData); michael@0: michael@0: void michael@0: Count(JSContext* aCx, const Sequence& aData); michael@0: michael@0: void michael@0: __noSuchMethod__(); michael@0: michael@0: private: michael@0: enum MethodName michael@0: { michael@0: MethodLog, michael@0: MethodInfo, michael@0: MethodWarn, michael@0: MethodError, michael@0: MethodException, michael@0: MethodDebug, michael@0: MethodTrace, michael@0: MethodDir, michael@0: MethodGroup, michael@0: MethodGroupCollapsed, michael@0: MethodGroupEnd, michael@0: MethodTime, michael@0: MethodTimeEnd, michael@0: MethodAssert, michael@0: MethodCount michael@0: }; michael@0: michael@0: void michael@0: Method(JSContext* aCx, MethodName aName, const nsAString& aString, michael@0: const Sequence& aData); michael@0: michael@0: void michael@0: AppendCallData(ConsoleCallData* aData); michael@0: michael@0: void michael@0: ProcessCallData(ConsoleCallData* aData); michael@0: michael@0: // If the first JS::Value of the array is a string, this method uses it to michael@0: // format a string. The supported sequences are: michael@0: // %s - string michael@0: // %d,%i - integer michael@0: // %f - double michael@0: // %o,%O - a JS object. michael@0: // %c - style string. michael@0: // The output is an array where any object is a separated item, the rest is michael@0: // unified in a format string. michael@0: // Example if the input is: michael@0: // "string: %s, integer: %d, object: %o, double: %d", 's', 1, window, 0.9 michael@0: // The output will be: michael@0: // [ "string: s, integer: 1, object: ", window, ", double: 0.9" ] michael@0: // michael@0: // The aStyles array is populated with the style strings that the function michael@0: // finds based the format string. The index of the styles matches the indexes michael@0: // of elements that need the custom styling from aSequence. For elements with michael@0: // no custom styling the array is padded with null elements. michael@0: void michael@0: ProcessArguments(JSContext* aCx, const nsTArray>& aData, michael@0: Sequence& aSequence, michael@0: Sequence& aStyles); michael@0: michael@0: void michael@0: MakeFormatString(nsCString& aFormat, int32_t aInteger, int32_t aMantissa, michael@0: char aCh); michael@0: michael@0: // Stringify and Concat all the JS::Value in a single string using ' ' as michael@0: // separator. michael@0: void michael@0: ComposeGroupName(JSContext* aCx, const nsTArray>& aData, michael@0: nsAString& aName); michael@0: michael@0: JS::Value michael@0: StartTimer(JSContext* aCx, const JS::Value& aName, michael@0: DOMHighResTimeStamp aTimestamp); michael@0: michael@0: JS::Value michael@0: StopTimer(JSContext* aCx, const JS::Value& aName, michael@0: DOMHighResTimeStamp aTimestamp); michael@0: michael@0: // The method populates a Sequence from an array of JS::Value. michael@0: void michael@0: ArgumentsToValueList(const nsTArray>& aData, michael@0: Sequence& aSequence); michael@0: michael@0: void michael@0: ProfileMethod(JSContext* aCx, const nsAString& aAction, michael@0: const Sequence& aData); michael@0: michael@0: JS::Value michael@0: IncreaseCounter(JSContext* aCx, const ConsoleStackEntry& aFrame, michael@0: const nsTArray>& aArguments); michael@0: michael@0: void michael@0: ClearConsoleData(); michael@0: michael@0: bool michael@0: ShouldIncludeStackrace(MethodName aMethodName); michael@0: michael@0: nsCOMPtr mWindow; michael@0: nsCOMPtr mTimer; michael@0: nsCOMPtr mStorage; michael@0: michael@0: LinkedList mQueuedCalls; michael@0: nsDataHashtable mTimerRegistry; michael@0: nsDataHashtable mCounterRegistry; michael@0: michael@0: uint64_t mOuterID; michael@0: uint64_t mInnerID; michael@0: michael@0: friend class ConsoleCallData; michael@0: friend class ConsoleCallDataRunnable; michael@0: friend class ConsoleProfileRunnable; michael@0: }; michael@0: michael@0: } // dom namespace michael@0: } // mozilla namespace michael@0: michael@0: #endif /* mozilla_dom_Console_h */