mirror of https://github.com/roytam1/kmeleon.git
4 changed files with 547 additions and 1 deletions
@ -0,0 +1,150 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
||||
* |
||||
* The contents of this file are subject to the Mozilla Public License Version |
||||
* 1.1 (the "License"); you may not use this file except in compliance with |
||||
* the License. You may obtain a copy of the License at |
||||
* http://www.mozilla.org/MPL/
|
||||
* |
||||
* Software distributed under the License is distributed on an "AS IS" basis, |
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
||||
* for the specific language governing rights and limitations under the |
||||
* License. |
||||
* |
||||
* The Original Code is mozilla.org code. |
||||
* |
||||
* The Initial Developer of the Original Code is |
||||
* Netscape Communications Corporation. |
||||
* Portions created by the Initial Developer are Copyright (C) 1998 |
||||
* the Initial Developer. All Rights Reserved. |
||||
* |
||||
* Contributor(s): |
||||
* |
||||
* Alternatively, the contents of this file may be used under the terms of |
||||
* either of the GNU General Public License Version 2 or later (the "GPL"), |
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
||||
* in which case the provisions of the GPL or the LGPL are applicable instead |
||||
* of those above. If you wish to allow use of your version of this file only |
||||
* under the terms of either the GPL or the LGPL, and not to allow others to |
||||
* use your version of this file under the terms of the MPL, indicate your |
||||
* decision by deleting the provisions above and replace them with the notice |
||||
* and other provisions required by the GPL or the LGPL. If you do not delete |
||||
* the provisions above, a recipient may use your version of this file under |
||||
* the terms of any one of the MPL, the GPL or the LGPL. |
||||
* |
||||
* ***** END LICENSE BLOCK ***** */ |
||||
|
||||
|
||||
|
||||
#include "nsCOMPtr.h" |
||||
#include "nsIFactory.h" |
||||
#include "nsIClassInfo.h" |
||||
#include "mozilla/ModuleUtils.h" |
||||
|
||||
struct nsModuleComponentInfo { |
||||
const char* mDescription; |
||||
nsCID mCID; |
||||
const char* mContractID; |
||||
mozilla::Module::ConstructorProcPtr mConstructor;
|
||||
}; |
||||
|
||||
// {3bc97f01-ccdf-11d2-bab8-b548654461fc}
|
||||
#define NS_GENERICFACTORY_CID \ |
||||
{ 0x3bc97f01, 0xccdf, 0x11d2, \
|
||||
{ 0xba, 0xb8, 0xb5, 0x48, 0x65, 0x44, 0x61, 0xfc } } |
||||
|
||||
// {3bc97f00-ccdf-11d2-bab8-b548654461fc}
|
||||
#define NS_IGENERICFACTORY_IID \ |
||||
{ 0x3bc97f00, 0xccdf, 0x11d2, \
|
||||
{ 0xba, 0xb8, 0xb5, 0x48, 0x65, 0x44, 0x61, 0xfc } } |
||||
|
||||
class nsIGenericFactory : public nsIFactory { |
||||
public: |
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IGENERICFACTORY_IID) |
||||
|
||||
NS_IMETHOD SetComponentInfo(const nsModuleComponentInfo *info) = 0; |
||||
NS_IMETHOD GetComponentInfo(const nsModuleComponentInfo **infop) = 0; |
||||
}; |
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIGenericFactory, NS_IGENERICFACTORY_IID); |
||||
|
||||
/**
|
||||
* Most factories follow this simple pattern, so why not just use a function |
||||
* pointer for most creation operations? |
||||
*/ |
||||
class nsGenericFactory : public nsIGenericFactory, public nsIClassInfo { |
||||
public: |
||||
NS_DEFINE_STATIC_CID_ACCESSOR(NS_GENERICFACTORY_CID) |
||||
|
||||
nsGenericFactory(const nsModuleComponentInfo *info = NULL); |
||||
|
||||
NS_DECL_ISUPPORTS |
||||
NS_DECL_NSICLASSINFO |
||||
|
||||
/* nsIGenericFactory methods */ |
||||
NS_IMETHOD SetComponentInfo(const nsModuleComponentInfo *info); |
||||
NS_IMETHOD GetComponentInfo(const nsModuleComponentInfo **infop); |
||||
|
||||
NS_IMETHOD CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult); |
||||
|
||||
NS_IMETHOD LockFactory(bool aLock); |
||||
|
||||
static NS_METHOD Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr); |
||||
private: |
||||
~nsGenericFactory(); |
||||
|
||||
const nsModuleComponentInfo *mInfo; |
||||
}; |
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "nsIModule.h" |
||||
#include "plhash.h" |
||||
|
||||
class nsGenericModule : public nsIModule |
||||
{ |
||||
public: |
||||
nsGenericModule(const char* moduleName,
|
||||
PRUint32 componentCount, |
||||
const nsModuleComponentInfo* components, |
||||
mozilla::Module::ConstructorProcPtr ctor); |
||||
|
||||
private: |
||||
~nsGenericModule(); |
||||
|
||||
public: |
||||
NS_DECL_ISUPPORTS |
||||
|
||||
NS_DECL_NSIMODULE |
||||
|
||||
struct FactoryNode |
||||
{ |
||||
FactoryNode(nsIFactory* fact, FactoryNode* next)
|
||||
{
|
||||
mFactory = fact;
|
||||
mNext = next; |
||||
} |
||||
~FactoryNode(){} |
||||
|
||||
nsCOMPtr<nsIFactory> mFactory; |
||||
FactoryNode* mNext; |
||||
}; |
||||
|
||||
|
||||
|
||||
|
||||
protected: |
||||
nsresult Initialize(nsIComponentManager* compMgr); |
||||
|
||||
void Shutdown(); |
||||
nsresult AddFactoryNode(nsIFactory* fact); |
||||
|
||||
PRBool mInitialized; |
||||
const char* mModuleName; |
||||
PRUint32 mComponentCount; |
||||
const nsModuleComponentInfo* mComponents; |
||||
FactoryNode* mFactoriesNotToBeRegistered; |
||||
mozilla::Module::ConstructorProcPtr mCtor; |
||||
//nsModuleDestructorProc mDtor;
|
||||
}; |
@ -0,0 +1,389 @@
|
||||
// Copyright (C) 2011 Milo Yip
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef RAPIDJSON_WRITER_H_ |
||||
#define RAPIDJSON_WRITER_H_ |
||||
|
||||
#include "rapidjson.h" |
||||
#include "internal/stack.h" |
||||
#include "internal/strfunc.h" |
||||
#include "internal/dtoa.h" |
||||
#include "internal/itoa.h" |
||||
#include "stringbuffer.h" |
||||
#include <new> // placement new |
||||
|
||||
#ifdef _MSC_VER |
||||
RAPIDJSON_DIAG_PUSH |
||||
RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
|
||||
#endif |
||||
|
||||
RAPIDJSON_NAMESPACE_BEGIN |
||||
|
||||
//! JSON writer
|
||||
/*! Writer implements the concept Handler.
|
||||
It generates JSON text by events to an output os. |
||||
|
||||
User may programmatically calls the functions of a writer to generate JSON text. |
||||
|
||||
On the other side, a writer can also be passed to objects that generates events,
|
||||
|
||||
for example Reader::Parse() and Document::Accept(). |
||||
|
||||
\tparam OutputStream Type of output stream. |
||||
\tparam SourceEncoding Encoding of source string. |
||||
\tparam TargetEncoding Encoding of output stream. |
||||
\tparam StackAllocator Type of allocator for allocating memory of stack. |
||||
\note implements Handler concept |
||||
*/ |
||||
template<typename OutputStream, typename SourceEncoding = UTF8<>, typename TargetEncoding = UTF8<>, typename StackAllocator = CrtAllocator> |
||||
class Writer { |
||||
public: |
||||
typedef typename SourceEncoding::Ch Ch; |
||||
|
||||
//! Constructor
|
||||
/*! \param os Output stream.
|
||||
\param allocator User supplied allocator. If it is null, it will create a private one. |
||||
\param levelDepth Initial capacity of stack. |
||||
*/ |
||||
Writer(OutputStream& os, StackAllocator* stackAllocator = 0, size_t levelDepth = kDefaultLevelDepth) :
|
||||
os_(&os), level_stack_(stackAllocator, levelDepth * sizeof(Level)), hasRoot_(false) {} |
||||
|
||||
Writer(StackAllocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : |
||||
os_(0), level_stack_(allocator, levelDepth * sizeof(Level)), hasRoot_(false) {} |
||||
|
||||
//! Reset the writer with a new stream.
|
||||
/*!
|
||||
This function reset the writer with a new stream and default settings, |
||||
in order to make a Writer object reusable for output multiple JSONs. |
||||
|
||||
\param os New output stream. |
||||
\code |
||||
Writer<OutputStream> writer(os1); |
||||
writer.StartObject(); |
||||
// ...
|
||||
writer.EndObject(); |
||||
|
||||
writer.Reset(os2); |
||||
writer.StartObject(); |
||||
// ...
|
||||
writer.EndObject(); |
||||
\endcode |
||||
*/ |
||||
void Reset(OutputStream& os) { |
||||
os_ = &os; |
||||
hasRoot_ = false; |
||||
level_stack_.Clear(); |
||||
} |
||||
|
||||
//! Checks whether the output is a complete JSON.
|
||||
/*!
|
||||
A complete JSON has a complete root object or array. |
||||
*/ |
||||
bool IsComplete() const { |
||||
return hasRoot_ && level_stack_.Empty(); |
||||
} |
||||
|
||||
/*!@name Implementation of Handler
|
||||
\see Handler |
||||
*/ |
||||
//@{
|
||||
|
||||
bool Null() { Prefix(kNullType); return WriteNull(); } |
||||
bool Bool(bool b) { Prefix(b ? kTrueType : kFalseType); return WriteBool(b); } |
||||
bool Int(int i) { Prefix(kNumberType); return WriteInt(i); } |
||||
bool Uint(unsigned u) { Prefix(kNumberType); return WriteUint(u); } |
||||
bool Int64(int64_t i64) { Prefix(kNumberType); return WriteInt64(i64); } |
||||
bool Uint64(uint64_t u64) { Prefix(kNumberType); return WriteUint64(u64); } |
||||
|
||||
//! Writes the given \c double value to the stream
|
||||
/*!
|
||||
\param d The value to be written. |
||||
\return Whether it is succeed. |
||||
*/ |
||||
bool Double(double d) { Prefix(kNumberType); return WriteDouble(d); } |
||||
|
||||
bool String(const Ch* str, SizeType length, bool copy = false) { |
||||
(void)copy; |
||||
Prefix(kStringType); |
||||
return WriteString(str, length); |
||||
} |
||||
|
||||
bool StartObject() { |
||||
Prefix(kObjectType); |
||||
new (level_stack_.template Push<Level>()) Level(false); |
||||
return WriteStartObject(); |
||||
} |
||||
|
||||
bool Key(const Ch* str, SizeType length, bool copy = false) { return String(str, length, copy); } |
||||
|
||||
bool EndObject(SizeType memberCount = 0) { |
||||
(void)memberCount; |
||||
RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); |
||||
RAPIDJSON_ASSERT(!level_stack_.template Top<Level>()->inArray); |
||||
level_stack_.template Pop<Level>(1); |
||||
bool ret = WriteEndObject(); |
||||
if (level_stack_.Empty()) // end of json text
|
||||
os_->Flush(); |
||||
return ret; |
||||
} |
||||
|
||||
bool StartArray() { |
||||
Prefix(kArrayType); |
||||
new (level_stack_.template Push<Level>()) Level(true); |
||||
return WriteStartArray(); |
||||
} |
||||
|
||||
bool EndArray(SizeType elementCount = 0) { |
||||
(void)elementCount; |
||||
RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); |
||||
RAPIDJSON_ASSERT(level_stack_.template Top<Level>()->inArray); |
||||
level_stack_.template Pop<Level>(1); |
||||
bool ret = WriteEndArray(); |
||||
if (level_stack_.Empty()) // end of json text
|
||||
os_->Flush(); |
||||
return ret; |
||||
} |
||||
//@}
|
||||
|
||||
/*! @name Convenience extensions */ |
||||
//@{
|
||||
|
||||
//! Simpler but slower overload.
|
||||
bool String(const Ch* str) { return String(str, internal::StrLen(str)); } |
||||
bool Key(const Ch* str) { return Key(str, internal::StrLen(str)); } |
||||
|
||||
//@}
|
||||
|
||||
protected: |
||||
//! Information for each nested level
|
||||
struct Level { |
||||
Level(bool inArray_) : valueCount(0), inArray(inArray_) {} |
||||
size_t valueCount; //!< number of values in this level
|
||||
bool inArray; //!< true if in array, otherwise in object
|
||||
}; |
||||
|
||||
static const size_t kDefaultLevelDepth = 32; |
||||
|
||||
bool WriteNull() { |
||||
os_->Put('n'); os_->Put('u'); os_->Put('l'); os_->Put('l'); return true; |
||||
} |
||||
|
||||
bool WriteBool(bool b) { |
||||
if (b) { |
||||
os_->Put('t'); os_->Put('r'); os_->Put('u'); os_->Put('e'); |
||||
} |
||||
else { |
||||
os_->Put('f'); os_->Put('a'); os_->Put('l'); os_->Put('s'); os_->Put('e'); |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
bool WriteInt(int i) { |
||||
char buffer[11]; |
||||
const char* end = internal::i32toa(i, buffer); |
||||
for (const char* p = buffer; p != end; ++p) |
||||
os_->Put(*p); |
||||
return true; |
||||
} |
||||
|
||||
bool WriteUint(unsigned u) { |
||||
char buffer[10]; |
||||
const char* end = internal::u32toa(u, buffer); |
||||
for (const char* p = buffer; p != end; ++p) |
||||
os_->Put(*p); |
||||
return true; |
||||
} |
||||
|
||||
bool WriteInt64(int64_t i64) { |
||||
char buffer[21]; |
||||
const char* end = internal::i64toa(i64, buffer); |
||||
for (const char* p = buffer; p != end; ++p) |
||||
os_->Put(*p); |
||||
return true; |
||||
} |
||||
|
||||
bool WriteUint64(uint64_t u64) { |
||||
char buffer[20]; |
||||
char* end = internal::u64toa(u64, buffer); |
||||
for (char* p = buffer; p != end; ++p) |
||||
os_->Put(*p); |
||||
return true; |
||||
} |
||||
|
||||
bool WriteDouble(double d) { |
||||
char buffer[25]; |
||||
char* end = internal::dtoa(d, buffer); |
||||
for (char* p = buffer; p != end; ++p) |
||||
os_->Put(*p); |
||||
return true; |
||||
} |
||||
|
||||
bool WriteString(const Ch* str, SizeType length) { |
||||
static const char hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; |
||||
static const char escape[256] = { |
||||
#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 |
||||
//0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00
|
||||
'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10
|
||||
0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20
|
||||
Z16, Z16, // 30~4F
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50
|
||||
Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF
|
||||
#undef Z16 |
||||
}; |
||||
|
||||
os_->Put('\"'); |
||||
GenericStringStream<SourceEncoding> is(str); |
||||
while (is.Tell() < length) { |
||||
const Ch c = is.Peek(); |
||||
if (!TargetEncoding::supportUnicode && (unsigned)c >= 0x80) { |
||||
// Unicode escaping
|
||||
unsigned codepoint; |
||||
if (!SourceEncoding::Decode(is, &codepoint)) |
||||
return false; |
||||
os_->Put('\\'); |
||||
os_->Put('u'); |
||||
if (codepoint <= 0xD7FF || (codepoint >= 0xE000 && codepoint <= 0xFFFF)) { |
||||
os_->Put(hexDigits[(codepoint >> 12) & 15]); |
||||
os_->Put(hexDigits[(codepoint >> 8) & 15]); |
||||
os_->Put(hexDigits[(codepoint >> 4) & 15]); |
||||
os_->Put(hexDigits[(codepoint ) & 15]); |
||||
} |
||||
else if (codepoint >= 0x010000 && codepoint <= 0x10FFFF) { |
||||
// Surrogate pair
|
||||
unsigned s = codepoint - 0x010000; |
||||
unsigned lead = (s >> 10) + 0xD800; |
||||
unsigned trail = (s & 0x3FF) + 0xDC00; |
||||
os_->Put(hexDigits[(lead >> 12) & 15]); |
||||
os_->Put(hexDigits[(lead >> 8) & 15]); |
||||
os_->Put(hexDigits[(lead >> 4) & 15]); |
||||
os_->Put(hexDigits[(lead ) & 15]); |
||||
os_->Put('\\'); |
||||
os_->Put('u'); |
||||
os_->Put(hexDigits[(trail >> 12) & 15]); |
||||
os_->Put(hexDigits[(trail >> 8) & 15]); |
||||
os_->Put(hexDigits[(trail >> 4) & 15]); |
||||
os_->Put(hexDigits[(trail ) & 15]);
|
||||
} |
||||
else |
||||
return false; // invalid code point
|
||||
} |
||||
else if ((sizeof(Ch) == 1 || (unsigned)c < 256) && escape[(unsigned char)c]) { |
||||
is.Take(); |
||||
os_->Put('\\'); |
||||
os_->Put(escape[(unsigned char)c]); |
||||
if (escape[(unsigned char)c] == 'u') { |
||||
os_->Put('0'); |
||||
os_->Put('0'); |
||||
os_->Put(hexDigits[(unsigned char)c >> 4]); |
||||
os_->Put(hexDigits[(unsigned char)c & 0xF]); |
||||
} |
||||
} |
||||
else |
||||
Transcoder<SourceEncoding, TargetEncoding>::Transcode(is, *os_); |
||||
} |
||||
os_->Put('\"'); |
||||
return true; |
||||
} |
||||
|
||||
bool WriteStartObject() { os_->Put('{'); return true; } |
||||
bool WriteEndObject() { os_->Put('}'); return true; } |
||||
bool WriteStartArray() { os_->Put('['); return true; } |
||||
bool WriteEndArray() { os_->Put(']'); return true; } |
||||
|
||||
void Prefix(Type type) { |
||||
(void)type; |
||||
if (level_stack_.GetSize() != 0) { // this value is not at root
|
||||
Level* level = level_stack_.template Top<Level>(); |
||||
if (level->valueCount > 0) { |
||||
if (level->inArray)
|
||||
os_->Put(','); // add comma if it is not the first element in array
|
||||
else // in object
|
||||
os_->Put((level->valueCount % 2 == 0) ? ',' : ':'); |
||||
} |
||||
if (!level->inArray && level->valueCount % 2 == 0) |
||||
RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name
|
||||
level->valueCount++; |
||||
} |
||||
else { |
||||
RAPIDJSON_ASSERT(!hasRoot_); // Should only has one and only one root.
|
||||
hasRoot_ = true; |
||||
} |
||||
} |
||||
|
||||
OutputStream* os_; |
||||
internal::Stack<StackAllocator> level_stack_; |
||||
bool hasRoot_; |
||||
|
||||
private: |
||||
// Prohibit copy constructor & assignment operator.
|
||||
Writer(const Writer&); |
||||
Writer& operator=(const Writer&); |
||||
}; |
||||
|
||||
// Full specialization for StringStream to prevent memory copying
|
||||
|
||||
template<> |
||||
inline bool Writer<StringBuffer>::WriteInt(int i) { |
||||
char *buffer = os_->Push(11); |
||||
const char* end = internal::i32toa(i, buffer); |
||||
os_->Pop(11 - (end - buffer)); |
||||
return true; |
||||
} |
||||
|
||||
template<> |
||||
inline bool Writer<StringBuffer>::WriteUint(unsigned u) { |
||||
char *buffer = os_->Push(10); |
||||
const char* end = internal::u32toa(u, buffer); |
||||
os_->Pop(10 - (end - buffer)); |
||||
return true; |
||||
} |
||||
|
||||
template<> |
||||
inline bool Writer<StringBuffer>::WriteInt64(int64_t i64) { |
||||
char *buffer = os_->Push(21); |
||||
const char* end = internal::i64toa(i64, buffer); |
||||
os_->Pop(21 - (end - buffer)); |
||||
return true; |
||||
} |
||||
|
||||
template<> |
||||
inline bool Writer<StringBuffer>::WriteUint64(uint64_t u) { |
||||
char *buffer = os_->Push(20); |
||||
const char* end = internal::u64toa(u, buffer); |
||||
os_->Pop(20 - (end - buffer)); |
||||
return true; |
||||
} |
||||
|
||||
template<> |
||||
inline bool Writer<StringBuffer>::WriteDouble(double d) { |
||||
char *buffer = os_->Push(25); |
||||
char* end = internal::dtoa(d, buffer); |
||||
os_->Pop(25 - (end - buffer)); |
||||
return true; |
||||
} |
||||
|
||||
RAPIDJSON_NAMESPACE_END |
||||
|
||||
#ifdef _MSC_VER |
||||
RAPIDJSON_DIAG_POP |
||||
#endif |
||||
|
||||
#endif // RAPIDJSON_RAPIDJSON_H_
|
@ -0,0 +1,8 @@
|
||||
#include "nsISupports.idl" |
||||
#include "nsIDOMEventTarget.idl" |
||||
|
||||
[scriptable, uuid(6e4995c3-deef-46a2-be73-154647710190)] |
||||
interface kmIHelper : nsISupports |
||||
{ |
||||
void initLogon(in nsIDOMEventTarget browser, in nsIDOMWindow win); |
||||
}; |
Loading…
Reference in new issue