aboutsummaryrefslogtreecommitdiff
path: root/files/zh-cn/mozilla/tech/xpcom
diff options
context:
space:
mode:
Diffstat (limited to 'files/zh-cn/mozilla/tech/xpcom')
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/glue/index.html71
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/guide/arrays/index.html573
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/guide/creating_components/an_overview_of_xpcom/index.html535
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/guide/creating_components/building_the_weblock_ui/index.html297
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/guide/creating_components/component_internals/index.html217
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/guide/creating_components/creating_the_component_code/index.html727
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/guide/creating_components/finishing_the_component/index.html337
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/guide/creating_components/index.html278
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/guide/creating_components/packaging_weblock/index.html136
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/guide/creating_components/preface/index.html83
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/guide/creating_components/resources/index.html10
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/guide/creating_components/setting_up_the_gecko_sdk/index.html204
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/guide/creating_components/starting_weblock/index.html1104
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/guide/creating_components/using_xpcom_components/index.html311
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/guide/creating_components/using_xpcom_utilities_to_make_things_easier/index.html388
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/guide/hashtables/index.html282
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/guide/index.html15
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/guide/internal_strings/index.html809
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/index.html44
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/interfacing_with_the_xpcom_cycle_collector/index.html141
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/language_bindings/components.utils.cloneinto/index.html290
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/language_bindings/components.utils.getglobalforobject/index.html41
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/language_bindings/index.html20
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/index.html49
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/使用javaxpcom在java应用程序中嵌入mozilla/index.html65
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/开发/index.html26
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/language_bindings/pyxpcom/index.html67
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/language_bindings/xpconnect/index.html67
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/observer_notifications/index.html880
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/index.html16
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/nscomptr/getting_started_guide/index.html478
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/nscomptr/index.html56
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/index.html14
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/interface/index.html11
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiaccessibleprovider/index.html45
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiclipboard/index.html91
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiclipboardhelper/index.html65
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiconsoleservice/index.html215
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/interface/nsidirectoryserviceprovider/index.html65
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/interface/nsidomclientrect/index.html92
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/interface/nsifile/index.html828
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/interface/nsifilepicker/index.html376
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/interface/nsihttpchannel/index.html365
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiidleservice/index.html119
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/interface/nsilocalfile/index.html478
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiprocess/index.html283
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiprompt/index.html55
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/interface/nsipromptservice/index.html696
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiscriptableunicodeconverter/index.html609
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/interface/nsisyncmessagesender/index.html65
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/interface/nsitimer/index.html285
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/interface/nsitraceablechannel/index.html71
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiuri/index.html407
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/reference/interface/nsixmlhttprequest/index.html90
-rw-r--r--files/zh-cn/mozilla/tech/xpcom/setting_http_request_headers/index.html261
55 files changed, 14203 insertions, 0 deletions
diff --git a/files/zh-cn/mozilla/tech/xpcom/glue/index.html b/files/zh-cn/mozilla/tech/xpcom/glue/index.html
new file mode 100644
index 0000000000..58bfdc731e
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/glue/index.html
@@ -0,0 +1,71 @@
+---
+title: XPCOM Glue
+slug: Mozilla/Tech/XPCOM/Glue
+tags:
+ - XPCOM
+ - 所有分类
+translation_of: Mozilla/Tech/XPCOM/Glue
+---
+<p>The XPCOM Glue is a static library which component developers and embedders can link against. It allows developers to link only against the frozen XPCOM method symbols and maintain compatibility with multiple versions of XPCOM.</p>
+<h3 id="Compiling_or_linking_against_XPCOM_headers" name="Compiling_or_linking_against_XPCOM_headers">Compiling or linking against XPCOM headers</h3>
+<p>There are three ways to compile/link against XPCOM headers/libraries:</p>
+<h4 id="Frozen_linkage:_dependent_glue_.28dependent_on_xpcom.dll.29" name="Frozen_linkage:_dependent_glue_.28dependent_on_xpcom.dll.29">Frozen linkage: dependent glue (dependent on xpcom.dll)</h4>
+<p>Code which wishes to use only frozen symbols but can tolerate a load-time dependency on xpcom.dll should link against xpcom.lib and xpcomglue_s.lib. This is the case for XPCOM components.</p>
+<h4 id="Frozen_linkage:_standalone_glue_.28no_DLL_dependencies.29" name="Frozen_linkage:_standalone_glue_.28no_DLL_dependencies.29">Frozen linkage: standalone glue (no DLL dependencies)</h4>
+<p>Embedding code which wishes to use only frozen symbols and cannot tolerate a load-time dependency on &lt;tt&gt;xpcom.dll&lt;/tt&gt; should &lt;tt&gt;#define XPCOM_GLUE 1&lt;/tt&gt; while compiling, and link against &lt;tt&gt;xpcomglue.lib&lt;/tt&gt;. It should
+ <i>
+ not</i>
+ link against &lt;tt&gt;xpcomglue_s.lib&lt;/tt&gt; or &lt;tt&gt;xpcom.lib&lt;/tt&gt;.</p>
+<p>In order to use XPCOM, the embedding application first needs to find where the XPCOM runtime is located. This is typically done using <a href="cn/GRE_GetGREPathWithProperties">GRE_GetGREPathWithProperties</a>. Then, the code must call <a href="cn/XPCOMGlueStartup">XPCOMGlueStartup</a>, which will dynamically link against the XPCOM runtime. Only then can the embedding application initialize and use XPCOM.</p>
+<p>This linkage strategy is used when an embedder needs to bootstrap an embedding app by finding a compatible <a href="cn/GRE">GRE</a>. Extension or XULRunner application components should use the dependent glue.</p>
+<p>Embedders using the standalone glue typically also need to avoid linking against NSPR as well.</p>
+<p>Emlak ilanlar</p>
+<h4 id="Using_Mozilla_internal_linkage" name="Using_Mozilla_internal_linkage">Using Mozilla internal linkage</h4>
+<p>Mozilla internal code defines MOZILLA_INTERNAL_API while compiling and links against xpcom.lib and xpcom_core.lib. In almost all cases embedders should *not* use internal linkage. Components using internal linkage will have shared-library dependencies against non-frozen symbols in the XPCOM libraries, and will not work with any other versions of XPCOM other than the one it was compiled against.</p>
+<p>Internal linkage will be unavailable to extension authors in XULRunner 1.9 (Firefox 3) because the nonfrozen symbols will not be exported from libxul. Extension and application authors currently using internal linkage should read the guide on <a href="cn/Migrating_from_Internal_Linkage_to_Frozen_Linkage">Migrating from Internal Linkage to Frozen Linkage</a>.</p>
+<h3 id="Threadsafe_nsISupports_implementations" name="Threadsafe_nsISupports_implementations">Threadsafe nsISupports implementations</h3>
+<p>When using glue libraries from Gecko 1.8 or later, a special step needs to be taken to use <code>NS_IMPL_THREADSAFE_ISUPPORTS
+ <i>
+ n</i>
+ </code>. This is because it forces a dependency on the NSPR library, which can otherwise be avoided. As described in <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=299664" title="FIXED: add support for MOZ_USE_NSPR w/ XPCOM_GLUE">bug 299664</a>, the preprocessor symbol <code>XPCOM_GLUE_USE_NSPR</code> needs to be defined.</p>
+<h3 id="Sample_Compiler.2FLinker_Flags" name="Sample_Compiler.2FLinker_Flags">Sample Compiler/Linker Flags</h3>
+<p>Code compiled using XPCOM headers should always &lt;tt&gt;#include "xpcom-config.h"&lt;/tt&gt; from the SDK, to ensure that XPCOM #defines are correct.</p>
+<table class="fullwidth-table">
+ <tbody>
+ <tr>
+ <th rowspan="2">Linking Strategy</th>
+ <th rowspan="2">Compiler Flags</th>
+ <th colspan="3">Linker Flags</th>
+ </tr>
+ <tr>
+ <th>Windows</th>
+ <th>Mac</th>
+ <th>Linux</th>
+ </tr>
+ <tr>
+ <td>Dependent Glue</td>
+ <td>&lt;tt style="white-space: pre"&gt;#include "xpcom-config.h"&lt;/tt&gt;</td>
+ <td>&lt;tt&gt;-LIBPATH:<var>c:/path/to/sdk/lib</var> xpcomglue_s.lib xpcom.lib nspr4.lib&lt;/tt&gt;</td>
+ <td>&lt;tt&gt;-L<var>/path/to/sdk/lib</var> -L<var>/path/to/sdk/bin</var> -Wl,-executable-path,<var>/path/to/sdk/bin</var> -lxpcomglue_s -lxpcom -lnspr4&lt;/tt&gt;</td>
+ <td>&lt;tt&gt;-L<var>/path/to/sdk/lib</var> -L<var>/path/to/sdk/bin</var> -Wl,-rpath-link,<var>/path/to/sdk/bin</var> -lxpcomglue_s -lxpcom -lnspr4&lt;/tt&gt;</td>
+ </tr>
+ <tr>
+ <td>Standalone Glue</td>
+ <td>&lt;tt style="white-space: pre"&gt;#include "xpcom-config.h"<br>
+ #define XPCOM_GLUE 1&lt;/tt&gt;</td>
+ <td>&lt;tt&gt;-LIBPATH:<var>c:/path/to/sdk/lib</var> xpcomglue.lib&lt;/tt&gt;</td>
+ <td>&lt;tt&gt;-L<var>/path/to/sdk/lib</var> -lxpcomglue&lt;/tt&gt;</td>
+ <td>&lt;tt&gt;-L<var>/path/to/sdk/lib</var> -lxpcomglue&lt;/tt&gt;</td>
+ </tr>
+ </tbody>
+</table>
+<h4 id="Notes" name="Notes">Notes</h4>
+<ul>
+ <li>Never link against xpcomglue.lib and xpcomglue_s.lib at the same time.</li>
+ <li>Never link against xpcomglue.lib and xpcom.lib at the same time.</li>
+ <li>These instructions are for Mozilla 1.8 and above. When using a SDK from Mozilla 1.7 or earlier, you must define MOZILLA_STRICT_API when using any form of the glue.</li>
+</ul>
+<h3 id="See_Also" name="See_Also">See Also</h3>
+<ul>
+ <li><a href="cn/Using_the_Gecko_SDK">Using the Gecko SDK</a></li>
+</ul>
diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/arrays/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/arrays/index.html
new file mode 100644
index 0000000000..53939ba6c0
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/guide/arrays/index.html
@@ -0,0 +1,573 @@
+---
+title: Array
+slug: Mozilla/Tech/XPCOM/Guide/Arrays
+tags:
+ - XPCOM
+ - 所有分类
+translation_of: Mozilla/Tech/XPCOM/Guide/Arrays
+---
+<p> </p>
+<h2 id="Introduction" name="Introduction">Introduction</h2>
+<h4 id="Array_types" name="Array_types">Array types</h4>
+<p>Mozilla has many array classes because each array is optimized for a particular usage pattern. This guide describes the available arrays as well as the enumerator classes that can be used to get to them. In this document the term Array refers to a container for multiple objects with a numeric, zero-based index.</p>
+<p>The standard array classes are:</p>
+<ul>
+ <li><code><a href="#nsIArray_.2F_nsIMutableArray">nsIArray</a></code> - a scriptable container for scriptable XPCOM objects. This array is read-only, and the interface does not provide any methods that will allow adding and removing members.</li>
+ <li><code>nsIMutableArray</code> - a scriptable container for scriptable XPCOM objects, which allows addition and removal of member objects. This interface actually derives from nsIArray.</li>
+ <li><code>nsCOMArray<span class="nowiki">&lt;T&gt;</span></code> - a C++ class which provides a typesafe, reference-counted container for pointers to a single type of COM object. This class is more or less a wrapper around nsVoidArray and thus shares most of its semantics.</li>
+ <li><code>nsTArray<span class="nowiki">&lt;T&gt;</span></code> - a C++ class which provides a typesafe container for objects or primitive types (pointers, integers, etc). The objects must define a default constructor and a copy constructor. To use <code>IndexOf</code> without providing a comparator, they must also define an <code>operator==</code>. For sorting without providing a comparator they must define an <code><span class="nowiki">operator&lt;</span></code>. Note that this class differs from the other array types by using unsigned indices.</li>
+ <li><code>nsVoidArray</code> - a C++ class which provides a generic container for any objects using the generic void * type.</li>
+ <li><code>nsStringArray</code> / <code>nsCStringArray</code> - a set of C++ classes for holding lists of string objects. Derived from nsVoidArray</li>
+ <li><code>nsAutoVoidArray</code> - a version of nsVoidArray which includes 8 entries of internal storage for the array data.</li>
+ <li><code>nsSmallVoidArray</code> - a replacement for nsVoidArray which is optimized to hold zero or one element.</li>
+</ul>
+<p>This handy chart may make it easier to understand the different arrays:</p>
+<table class="fullwidth-table">
+ <tbody>
+ <tr>
+ <th>Class</th>
+ <th>Data Type</th>
+ <th>Scriptable?</th>
+ <th>Typesafe?</th>
+ <th>Can be modified?</th>
+ <th>Built in buffer?</th>
+ <th>Ownership</th>
+ </tr>
+ <tr class="even">
+ <td><code><a href="#nsIArray_.2F_nsIMutableArray">nsIArray</a></code></td>
+ <td>XPCOM object</td>
+ <td>Yes</td>
+ <td>No</td>
+ <td>No</td>
+ <td>No</td>
+ <td>Reference Counted, Weak/Strong</td>
+ </tr>
+ <tr class="odd">
+ <td><code>nsIMutableArray</code></td>
+ <td>XPCOM object</td>
+ <td>Yes</td>
+ <td>No</td>
+ <td>Yes</td>
+ <td>No</td>
+ <td>Reference Counted, Weak/Strong</td>
+ </tr>
+ <tr class="even">
+ <td><code>nsCOMArray&lt;T&gt;</code></td>
+ <td>XPCOM object</td>
+ <td>No</td>
+ <td>Yes</td>
+ <td>Yes*</td>
+ <td>No</td>
+ <td>Reference Counted, Strong</td>
+ </tr>
+ <tr class="odd">
+ <td><code>nsTArray&lt;T&gt;</code></td>
+ <td>Any that has a default constructor and copy constructor</td>
+ <td>No</td>
+ <td>Yes</td>
+ <td>Yes*</td>
+ <td>No</td>
+ <td>Can hold objects directly, in which case it owns them. When holding pointers, doesn't own the pointer.</td>
+ </tr>
+ <tr class="even">
+ <td><code>nsVoidArray</code></td>
+ <td>Any</td>
+ <td>No</td>
+ <td>No</td>
+ <td>Yes*</td>
+ <td>No</td>
+ <td>Weak / None</td>
+ </tr>
+ <tr class="odd">
+ <td><code>nsStringArray</code><br>
+ <code>nsCStringArray</code></td>
+ <td><code>nsString</code><br>
+ <code>nsCString</code></td>
+ <td>No</td>
+ <td>Yes</td>
+ <td>Yes*</td>
+ <td>No</td>
+ <td>Private (copies strings)</td>
+ </tr>
+ <tr class="even">
+ <td><code>nsAutoVoidArray</code></td>
+ <td>Any</td>
+ <td>No</td>
+ <td>No</td>
+ <td>Yes*</td>
+ <td>Yes</td>
+ <td>Weak / None</td>
+ </tr>
+ <tr class="odd">
+ <td><code>nsSmallVoidArray</code></td>
+ <td>Any</td>
+ <td>No</td>
+ <td>No</td>
+ <td>Yes*</td>
+ <td>No</td>
+ <td>Weak / None</td>
+ </tr>
+ <tr class="even">
+ <td><code>nsISupportsArray</code></td>
+ <td>XPCOM Object</td>
+ <td>Yes</td>
+ <td>No</td>
+ <td>Yes*</td>
+ <td>No</td>
+ <td>Reference Counted, Strong</td>
+ </tr>
+ </tbody>
+</table>
+<p>(*) Note: Concrete C++ arrays can be made read-only by declaring them const. For example:</p>
+<pre class="eval">// HandleList cannot modify the array because of const
+void HandleList(const nsVoidArray&amp;);
+</pre>
+<h4 id="In-place_enumeration" name="In-place_enumeration">In-place enumeration</h4>
+<p>Most of the arrays presented here provide callback-style means to enumerate members of an array. Instead of incrementally accessing each element of the array by its index, the arrays provide a way to pass in a callback function that will be called for each element in the array.</p>
+<p>For most concrete C++ classes like <code>nsVoidArray</code> and <code>nsCOMArray&lt;T&gt;</code>, indexing should be faster than the callback-style enumeration, because accessing an indexed member of such an array is usually very fast, while enumeration has slight function call overhead. In the case of scriptable arrays like nsIArray however, the enumeration mechanism is often preferred because it avoids the AddRef / Release overhead that comes from accessing each object.</p>
+<p>The only functional drawback to in-place enumeration is that you cannot manipulate the array itself during the enumeration. For example, you should not delete elements of an array during the enumeration as this will often confuse the loop which is enumerating the array.</p>
+<h4 id="Enumerators" name="Enumerators">Enumerators</h4>
+<p>Most arrays provide access to an object which is used to enumerate members of the array. These Enumerators maintain state about the current position in the array. Enumerators are used to access the elements in an ordered way, without relying on the underlying array type. These enumerators include:</p>
+<ul>
+ <li><code>nsISimpleEnumerator</code> - an enumerator for COM objects.</li>
+ <li><code>nsIStringEnumerator</code> / <code>nsIUTF8StringEnumerator</code> - enumerators for strings</li>
+</ul>
+<h4 id="Obsolete_arrays_.2F_enumerators" name="Obsolete_arrays_.2F_enumerators">Obsolete arrays / enumerators</h4>
+<p>There are some deprecated classes which <b>should not be used by new code</b>.</p>
+<ul>
+ <li><code>nsISupportsArray</code> - obsoleted by <code><a href="#nsIArray_.2F_nsIMutableArray">nsIArray</a></code>, use that instead.</li>
+ <li><code>nsIEnumerator</code> - obsoleted by <code>nsISimpleEnumerator</code>, use that instead.</li>
+ <li><code>nsIBidirectionalEnumerator</code> - obsoleted by <code>nsISimpleEnumerator</code>, use that instead.</li>
+ <li><code>nsVoidArray</code> - <code>nsTArray<span class="nowiki">&lt;T&gt;</span></code> is preferred. Using <code>nsAutoVoidArray</code> is still ok, since that saves an allocation over using <code>nsTArray<span class="nowiki">&lt;T&gt;</span>(8)</code>.</li>
+</ul>
+<h2 id="Which_Array_should_I_use.3F" name="Which_Array_should_I_use.3F">Which Array should I use?</h2>
+<p>Do not use <code>nsISupportsArray</code>; it is deprecated.</p>
+<p>Does your array need to be scriptable? If so, use <code>nsIArray</code>.</p>
+<p>Example: an array attribute in an IDL file would be <code>nsIArray</code>.</p>
+<p>Will your array store non-refcounted objects and need automatic resizing? If so, use <code>nsTArray<span class="nowiki">&lt;T&gt;</span></code>.</p>
+<p>Example: an array of integers or an array of strings.</p>
+<p>Will your array store non-refcounted objects and be a fixed size? If so, just use a native C++ array unless you need the enumeration options on <code>nsTArray<span class="nowiki">&lt;T&gt;</span></code>.</p>
+<p>Example: an array of error message static const char* pointers.</p>
+<p>Are all the things you are storing interface pointers to instances of the same interface? If so, use <code>nsCOMArray</code>.</p>
+<p>Example: a content node's list of <code>nsIContent</code> children.</p>
+<p>Otherwise use <code>nsIArray</code> and make liberal use of <code>QueryElementAt()</code>.</p>
+<p>The point of <code>nsCOMArray</code> is that it's a template, and all the pointers in it must be pointers to the same type; it's nice to be able to use it because you get type-safety and don't have to spend time and code QIing (like you have to with <code>nsIArray</code>).</p>
+<h2 id="Array_Guidelines" name="Array_Guidelines">Array Guidelines</h2>
+<p>Here are a few simple rules which will keep your code clean and your developers happy:</p>
+<ul>
+ <li>Use typesafe arrays like <code>nsCOMArray<span class="nowiki">&lt;T&gt;</span></code> <code>nsTArray<span class="nowiki">&lt;T&gt;</span></code> wherever possible.</li>
+ <li>Avoid all obsolete arrays and enumerators.</li>
+ <li>Avoid creating temporary arrays.</li>
+</ul>
+<h2 id="Scriptable_Arrays" name="Scriptable_Arrays">Scriptable Arrays</h2>
+<h3 id="nsIArray_.2F_nsIMutableArray" name="nsIArray_.2F_nsIMutableArray">nsIArray / nsIMutableArray</h3>
+<h4 id="Usage" name="Usage">Usage</h4>
+<p><code>nsIArray</code> is useful if you need to pass arrays of COM objects through interfaces or require a scriptable array. It can hold strong or weak references to its container objects. This basic interface only allows querying of existing elements in the array. The methods that modify the array have been broken out into <code>nsIMutableArray</code>.</p>
+<p>An <code>nsIArray</code> implementation can be created from C++ with the function <code>NS_NewArray(nsIMutableArray**);</code>. The created array implements <code>nsIMutableArray</code> and <code>nsIArray</code>. Since <code>nsIArray</code> derives from <code>nsIMutableArray</code>, the resulting array can be cast to a read-only array.</p>
+<pre class="eval">void GetList(nsIArray** aResult) {
+ nsCOMPtr&lt;nsIMutableArray&gt; array;
+ NS_NewArray(getter_AddRefs(array));
+
+ // append some elements
+ ...
+
+ // return it to the caller
+ *aResult = array;
+ NS_ADDREF(*aResult);
+}
+</pre>
+<h4 id="Access_to_elements" name="Access_to_elements">Access to elements</h4>
+<p>Since <code>nsIArray</code> is a regular XPCOM object, its interfaces follows the standard conventions of ownership. Access to specific elements is through <code>QueryElementAt</code>, which is similar to <code>QueryInterface</code>, but it takes a specific index.</p>
+<pre class="eval">void NotifyObservers(nsIArray* aArray) {
+ PRUint32 length;
+ aArray-&gt;GetLength(&amp;length);
+ for (PRUint32 i=0; i&lt;length; ++i) {
+ nsCOMPtr&lt;nsIMyObserver&gt; element;
+ aArray-&gt;QueryElementAt(i, NS_GET_IID(nsIElement),
+ getter_AddRefs(element));
+ element-&gt;Observe();
+ }
+}
+</pre>
+<p>A simpler option is to use the helper <code>do_QueryElementAt</code> which is typesafe.</p>
+<pre class="eval">void NotifyObservers(nsIArray* aArray) {
+ PRUint32 length;
+ aArray-&gt;GetLength(&amp;length);
+ for (PRUint32 i=0; i&lt;length; ++i) {
+ nsCOMPtr&lt;nsIMyObserver&gt; element =
+ do_QueryElementAt(aArray, i);
+ element-&gt;Observe();
+ }
+}
+</pre>
+<h4 id="Passing_as_a_parameter" name="Passing_as_a_parameter">Passing as a parameter</h4>
+<p>Since <code>nsIArray</code> is an XPCOM object, it should be passed as a pointer. To distinguish between read-only arrays and writable arrays, you should make sure to pass a nsIArray or <code>nsIMutableArray</code> as appropriate.</p>
+<p>When the array can or should be modified, then use nsIMutableArray:</p>
+<pre class="eval">// array is read-only because it uses nsIArray
+void PrintSize(nsIArray* elements) {
+ PRUint32 count;
+ elements-&gt;GetLength(&amp;count);
+ printf("There are %d elements.\n", count);
+}
+
+// using nsIMutableArray, so callee may modify
+void TweakArray(nsIMutableArray* elements) {
+ elements-&gt;RemoveElementAt(0);
+ elements-&gt;AppendElement(newElement, PR_FALSE);
+}
+</pre>
+<p>While it is usually possible to call <code>QueryInterface</code> on an <code>nsIArray</code> to get access to the <code>nsIMutableArray</code> interface, this is against convention and it should be avoided.</p>
+<pre class="eval">// no need for the double-pointer, and this violates XPCOM rules
+// which expect acess to a new object
+void TweakArray(nsIMutableArray** elements) {
+ // ugh, extra indirection!
+ *elements-&gt;RemoveElementAt(0);
+ *elements-&gt;AppendElement(newElement, PR_FALSE);
+}
+</pre>
+<h4 id="In-place_enumeration_2" name="In-place_enumeration_2">In-place enumeration</h4>
+<p>When accessing all members of an <code>nsIArray</code>, in-place enumeration is preferred over indexed access. However, I seem to have forgotten to implement that. Good thing the interface is under review. Sorry!</p>
+<h4 id="Enumerators_2" name="Enumerators_2">Enumerators</h4>
+<p>Creating an enumerator from an <code>nsIArray</code> is easy. The method <code>Enumerate()</code> returns a <code>nsISimpleEnumerator</code> which accesses all the elements in the array. Often, simply accessing an array by index, using <code>QueryElementAt</code> is faster. See the section on Enumerators to learn when to properly use enumerators.</p>
+<p>For example, if you need to iterate an array returned from another object, you might use <code>Enumerate()</code>.</p>
+<pre class="eval">...
+// get the array
+nsCOMPtr&lt;nsIArray&gt; array;
+foo-&gt;GetElements(getter_AddRefs(array));
+
+// make an enumerator
+nsCOMPtr&lt;nsISimpleEnumerator&gt; enumerator;
+array-&gt;Enumerate(getter_AddRefs(enumerator));
+
+// now enumerate the elements
+...
+</pre>
+<h2 id="Typesafe_Arrays" name="Typesafe_Arrays">Typesafe Arrays</h2>
+<h3 id="nsCOMArray.3CT.3E" name="nsCOMArray.3CT.3E">nsCOMArray&lt;T&gt;</h3>
+<p><code>nsCOMArray&lt;T&gt;</code> is a typesafe wrapper around <code>nsVoidArray</code>, so it has a similar API. It enforces both typesafety and XPCOM reference counting by keeping an owning reference to each element in the array.</p>
+<h4 id="Usage_2" name="Usage_2">Usage</h4>
+<p>It is most often used as a member of a C++ class to store a list of well-typed XPCOM objects. It is also usually declared as an inline member rather than a pointer. As a class member, <code>nsCOMArray&lt;T&gt;</code> is preferred over <code>nsIArray</code> when access to the array is confined to the class itself.</p>
+<p>For example, here is its use in a class:</p>
+<pre class="eval">class NodeContainer {
+public:
+ void AddNode(nsINode* node);
+
+private:
+ nsCOMArray&lt;nsINode&gt; mNodes;
+};
+
+// typesafety of mNodes ensures that we only append an nsINode*
+void NodeContainer::AddNode(nsINode* node) {
+ mNodes.AppendObject(node);
+}
+
+</pre>
+<p><code>nsCOMArray&lt;T&gt;</code> can also be declared on the stack to collect a temporary list of objects and manipulate them. When the object goes out of scope, all its members are released.</p>
+<pre class="eval">void ProcessVisibleItems()
+{
+ // temporary stack-based nsCOMArray
+ nsCOMArray&lt;nsIFoo&gt; fooItems;
+ GetCompleteList(fooItems);
+
+ // now filter out non visible objects
+ // doing this backwards
+ PRUint32 i = fooItems.Count();
+ while (i &gt; 0) {
+ --i;
+ PRBool isVisible;
+ fooItems[i]-&gt;GetIsVisible(&amp;isVisible);
+ if (!isVisible) {
+ fooItems.RemoveObjectAt(i);
+ }
+ }
+
+ // now deal with the processed list
+ ProcessList(fooItems);
+
+ // fooItems will release all its members
+ // when it goes out of scope
+}
+</pre>
+<h4 id="Access_to_elements_2" name="Access_to_elements_2">Access to elements</h4>
+<p><code>nsCOMArray&lt;T&gt;</code> is a concrete C++ class, and so the [] operator is used to access its members. When using the [] operator, the reference count is unchanged. This allows direct processing of array elements without worrying about calling <code>Release()</code>.</p>
+<p>For example, this code calls the same method on each member:</p>
+<pre class="eval">void NotifyObservers(const nsCOMArray&lt;nsIMyObserver&gt;&amp; observers) {
+ // Using [] doesn't leak!
+ for (PRInt32 i = observers.Count() - 1; i &gt;= 0 ; i--)
+ observers[i]-&gt;Observe();
+}
+</pre>
+<p>Be careful with this though, you could end up with a weak pointer if you're converting from non-nsCOMArray code.</p>
+<pre class="eval">// old version, relied on automatic addref
+// mElements is an nsISupportsArray*
+void GetFirstObject(nsIElement** aResult) {
+ // no need to call NS_ADDREF - this does it for you
+ mElements-&gt;QueryElementAt(0, NS_GET_IID(nsIElement),
+ (void**)aResult);
+}
+
+// new version, make sure to call NS_ADDREF()
+// mElements is now a nsCOMArray&lt;nsIElement&gt;
+void GetFirstObject(nsIElement** aResult) {
+ *aResult = mElements[0];
+ NS_ADDREF(*aResult);
+}
+</pre>
+<h4 id="Passing_as_a_parameter_2" name="Passing_as_a_parameter_2">Passing as a parameter</h4>
+<p>When passing <code>nsCOMArray&lt;T&gt;</code> among functions, the convention is to pass by reference. Also be sure to use const if you want to enforce that the array is read-only.</p>
+<p>Here is an example with a read-only and a writable array:</p>
+<pre class="eval">// array is read-only because of const
+void PrintSize(const nsCOMArray&lt;nsIElements&gt;&amp; elements) {
+ printf("There are %d elements.\n", elements.Count());
+}
+
+// no const, so we can modify the array
+void TweakArray(nsCOMArray&lt;nsIElement&gt;&amp; elements, nsIElement* newElement) {
+ elements.RemoveObjectAt(0);
+ elements.AppendObject(newElement);
+}
+</pre>
+<h4 id="In-place_enumeration_3" name="In-place_enumeration_3">In-place enumeration</h4>
+<p>The callback-based enumeration in <code>nsCOMArray&lt;T&gt;</code> is about as fast as, if not faster than, standard loop-based iteration. The callback mechanism can be useful when integrating with existing callback-style code however.</p>
+<p>One particularly nice thing about the callback mechanism is that it is typesafe. For instance:</p>
+<pre class="eval">PR_CALLBACK PRBool getFirstVisible(nsIElement* element, void* closure) {
+ PRBool isVisible;
+ element-&gt;IsVisible(&amp;isVisible);
+
+ // stop at first object
+ if (isVisible) {
+ NS_STATIC_CAST(ClosureObject*,closure)-&gt;element = element;
+ return PR_FALSE;
+ }
+ return PR_TRUE;
+}
+
+...
+// enumerate to find the object
+ClosureObject closureObject = { 0 };
+if (!mElements.EnumerateForwards(getFirstVisible, closureObject))
+ processElement(closureObject-&gt;element);
+...
+</pre>
+<h4 id="Enumerators_3" name="Enumerators_3">Enumerators</h4>
+<p>A <code>nsISimpleEnumerator</code> can be created to provide access to a <code>nsCOMArray&lt;T&gt;</code>. When the enumerator is created, it takes a snapshot of the elements in the array, so that the enumerator can outlive the array.</p>
+<p>To create the enumerator, use <code>NS_NewArrayEnumerator(nsISimpleEnumerator**, const nsCOMArray&lt;T&gt;&amp;)</code>. For example:</p>
+<pre class="eval">// mElements is an nsCOMArray&lt;nsIElement&gt;
+nsFoo::GetElements(nsISimpleEnumerator** aResult) {
+ return NS_NewArrayEnumerator(aResult, mElements);
+}
+</pre>
+<h3 id="nsTArray.3CT.3E" name="nsTArray.3CT.3E">nsTArray&lt;T&gt;</h3>
+<p><code>nsTArray&lt;T&gt;</code> is a typesafe array for holding various objects. It can be used to hold objects directly, not just pointers to objects.</p>
+<h4 id="Usage_3" name="Usage_3">Usage</h4>
+<p>It is most often used as a member of a C++ class to store a list of well-typed objects. It is also usually declared as an inline member rather than a pointer. As a class member, <code>nsTArray&lt;T&gt;</code> is preferred over <code>nsVoidArray</code>.</p>
+<p>For example, here is its use in a class:</p>
+<pre class="eval">class MediaList {
+public:
+ void AddMedium(const nsString&amp; aMedium);
+
+private:
+ nsTArray&lt;nsString&gt; mMedia;
+};
+
+// typesafety of mMedia ensures that we only append an nsString
+void NodeContainer::AddMedium(const nsString&amp; aMedium) {
+ mMedia.AppendElement(aMedium);
+}
+
+</pre>
+<p><code>nsTArray&lt;T&gt;</code> can also be declared on the stack to collect a temporary list of objects and manipulate them. When the object goes out of scope, all its members have their destructors called. Note that if the <code>nsTArray&lt;T&gt;</code> holds pointers to objects, the objects will not be deleted (and hence not have their destructors called).</p>
+<pre class="eval">void ProcessVisibleItems()
+{
+ // temporary stack-based nsTArray
+ nsTArray&lt;FooStruct&gt; fooItems;
+ GetCompleteList(fooItems);
+
+ // now filter out non visible objects
+ // doing this backwards
+ PRUint32 i = fooItems.Length();
+ while (i &gt; 0) {
+ --i;
+ PRBool isVisible;
+ fooItems[i]-&gt;GetIsVisible(&amp;isVisible);
+ if (!isVisible) {
+ fooItems.RemoveElementAt(i);
+ }
+ }
+
+ // now deal with the processed list
+ ProcessList(fooItems);
+
+ // fooItems will call the destructors of all the FooStruct objects
+ // when it goes out of scope
+}
+</pre>
+<h4 id="Access_to_elements_3" name="Access_to_elements_3">Access to elements</h4>
+<p><code>nsTArray&lt;T&gt;</code> is a concrete C++ class, and so the [] operator is used to access its members.</p>
+<p>For example, this code calls the same method on each member:</p>
+<pre class="eval">void NotifyObservers(const nsTArray&lt;ObserverClass*&gt;&amp; observers) {
+ for (PRUint32 i = observers.Length(); i &gt; 0 ; ) {
+ --i;
+ observers[i]-&gt;Observe();
+ }
+}
+</pre>
+<h4 id="Passing_as_a_parameter_3" name="Passing_as_a_parameter_3">Passing as a parameter</h4>
+<p>When passing <code>nsTArray&lt;T&gt;</code> among functions, the convention is to pass by reference. Also be sure to use <code>const</code> if you want to enforce that the array is read-only.</p>
+<p>Here is an example with a read-only and a writable array:</p>
+<pre class="eval">// array is read-only because of const
+void PrintSize(const nsTArray&lt;nsElement&gt;&amp; elements) {
+ printf("There are %d elements.\n", elements.Length());
+}
+
+// no const, so we can modify the array
+void TweakArray(nsTArray&lt;nsElement&gt;&amp; elements,
+ const nsElement&amp; newElement) {
+ elements.RemoveElementAt(0);
+ elements.AppendElement(newElement);
+}
+</pre>
+<h4 id="In-place_enumeration_4" name="In-place_enumeration_4">In-place enumeration</h4>
+<p>There are no enumerator objects that work on an <code>nsTArray&lt;T&gt;</code>.</p>
+<h2 id="C.2B.2B_Arrays" name="C.2B.2B_Arrays">C++ Arrays</h2>
+<h3 id="nsVoidArray" name="nsVoidArray">nsVoidArray</h3>
+<p><code>nsVoidArray</code> is a concrete C++ class that allows for storage of any arbitrary object. The base type for all objects is void *. When converting to/from a void *, use <code>NS_STATIC_CAST</code> to ensure that no const-ness is lost.</p>
+<p>Note that <code>nsVoidArray</code> defines no semantics of ownership of its objects. Depending on its use, the array may either own the objects that it points to, or its member may be pointers to existing objects that are owned by another data structure. Because nsVoidArray itself does not define any ownership rules, it is up to the consumer to know when it is appropriate to free objects out of the array.</p>
+<p>This implies that when an <code>nsVoidArray</code> goes out of scope, seperate code must free any memory that is semantically owned by the array. This should always be documented in the declaration of the array instance.</p>
+<p><code>nsCOMArray&lt;T&gt;</code> was designed to eliminate some of the overhead of using nsVoidArray when using COM objects. If your code is using <code>nsVoidArray</code> to keep references to COM objects, consider converting it to <code>nsCOMArray&lt;T&gt;</code>.</p>
+<h4 id="Usage_4" name="Usage_4">Usage</h4>
+<p><code>nsVoidArray</code> is often used as a member variable in a class. Remember to document ownership!</p>
+<pre class="eval">struct FooElement {
+ ...
+};
+
+class nsFoo : nsIFoo {
+ ...
+ virtual ~nsFoo();
+ ...
+
+ private:
+ // mElements owns a list of FooElement structs,
+ // which must be deleted when this object goes away
+ nsVoidArray mElements;
+
+ // mVisibleElements contains weak (non-owning) references
+ // to elements in mElements, and does not need to be cleaned up
+ nsVoidArray mVisibleElements;
+};
+
+nsFoo::~nsFoo() {
+ // mVisibleElements is fine, but
+ // don't forget to clean up mElements!
+ PRUint32 i, count = mElements.Count();
+ for (i=0; i&lt;count; ++i)
+ delete NS_STATIC_CAST(FooElement*, mElements[i]);
+ }
+
+</pre>
+<p>As you can see, <code>nsVoidArray</code> has some context-specific overhead to make sure memory is cleaned up appropriately.</p>
+<h4 id="Access_to_elements_4" name="Access_to_elements_4">Access to elements</h4>
+<p>The [] operator is used to access member variables. Don't forget to use <code>NS_STATIC_CAST()</code>.</p>
+<pre class="eval">for (i=0; i&lt;count; ++i) {
+ FooElement* element = NS_STATIC_CAST(FooElement*,mElements[i]);
+ // now manipulate element
+}
+
+</pre>
+<h4 id="Passing_as_a_parameter_4" name="Passing_as_a_parameter_4">Passing as a parameter</h4>
+<p>Like other concrete C++ classes, passing by reference using the &amp; syntax is preferred.</p>
+<h4 id="In-place_enumeration_5" name="In-place_enumeration_5">In-place enumeration</h4>
+<h4 id="Enumerators_4" name="Enumerators_4">Enumerators</h4>
+<h3 id="nsStringArray_.2F_nsCStringArray" name="nsStringArray_.2F_nsCStringArray">nsStringArray / nsCStringArray</h3>
+<h4 id="Usage_5" name="Usage_5">Usage</h4>
+<h4 id="Access_to_elements_5" name="Access_to_elements_5">Access to elements</h4>
+<h4 id="Passing_as_a_parameter_5" name="Passing_as_a_parameter_5">Passing as a parameter</h4>
+<h4 id="In-place_enumeration_6" name="In-place_enumeration_6">In-place enumeration</h4>
+<h4 id="Enumerators_5" name="Enumerators_5">Enumerators</h4>
+<h3 id="nsAutoVoidArray" name="nsAutoVoidArray">nsAutoVoidArray</h3>
+<h4 id="Usage_6" name="Usage_6">Usage</h4>
+<h4 id="Access_to_elements_6" name="Access_to_elements_6">Access to elements</h4>
+<h4 id="Passing_as_a_parameter_6" name="Passing_as_a_parameter_6">Passing as a parameter</h4>
+<h4 id="In-place_enumeration_7" name="In-place_enumeration_7">In-place enumeration</h4>
+<h4 id="Enumerators_6" name="Enumerators_6">Enumerators</h4>
+<h3 id="nsSmallVoidArray" name="nsSmallVoidArray">nsSmallVoidArray</h3>
+<h4 id="Usage_7" name="Usage_7">Usage</h4>
+<h4 id="Access_to_elements_7" name="Access_to_elements_7">Access to elements</h4>
+<h4 id="Passing_as_a_parameter_7" name="Passing_as_a_parameter_7">Passing as a parameter</h4>
+<h4 id="In-place_enumeration_8" name="In-place_enumeration_8">In-place enumeration</h4>
+<h4 id="Enumerators_7" name="Enumerators_7">Enumerators</h4>
+<h2 id="Enumerators_8" name="Enumerators_8">Enumerators</h2>
+<p>Enumerators are very simple, structure-free objects for visiting each member of a set of objects. The enumerators are used as a generic interface for arrays, hashtables, and other constructs which contain one or more objects. When designing public interfaces, enumerators are the preferred mechanism for accessing these structures because they hide the details of the implementation behind the interface.</p>
+<h3 id="nsISimpleEnumerator" name="nsISimpleEnumerator">nsISimpleEnumerator</h3>
+<p><code>nsISimpleEnumerator</code> is a generic enumerator for enumerating a list of any XPCOM object. There are many implementations of <code>nsISimpleEnumerator</code>, including one that enumerates <code>nsIArray</code> objects, and another one for <code>nsCOMArray</code>. It is very common for other interfaces which support <code>nsISimpleEnumerator</code> to make their own implementations.</p>
+<h3 id="nsIStringEnumerator" name="nsIStringEnumerator">nsIStringEnumerator</h3>
+<p>String enumerators provide an easy way to pass a list of strings around with minimal copying. Both unicode strings and UTF8-encoded strings are supported. For more information about the different types of strings, see the String Guide.</p>
+<p>String enumerators can be created from <code>nsStringArray</code> or <code>nsCStringArray</code> objects. The implementation of the string enumerator interfaces for <code>nsStringArray</code> and <code>nsCStringArray</code> supports conversion between UTF8 and Unicode, and can be QueryInterface'd back and forth between <code>nsIStringEnumerator</code> and <code>nsIUTF8StringEnumerator</code>.</p>
+<p>To create an nsIStringEnumerator for an <code>nsStringArray</code>, you can use one of the variations of <code>NS_NewStringEnumerator</code>. There are also corresponding enumerators and helpers for UTF8 strings. In the examples below, <code>NS_NewUTF8StringEnumerator</code> can be used along with <code>nsIUTF8StringEnumerator</code> and <code>nsCStringArray</code>.</p>
+<p>This first example demonstrates the case where a class which owns an <code>nsStringArray</code>, and are returns an <code>nsIStringEnumerator</code> to a caller. You can use the variation of <code>NS_NewStringEnumerator</code> that ensures the owner of the array outlives the enumerator. This is necessary because nsStringArray is not reference counted. Without holding a reference to the owner, the enumerator could be left with a dangling pointer to a deleted <code>nsStringArray</code>.</p>
+<pre class="eval">class nsFoo : nsIFoo {
+...
+private:
+ nsStringArray mElementNames;
+};
+
+nsFoo::GetElementNames(nsIStringEnumerator** aResult)
+{
+ // pass in "this" to make sure the enumerator
+ // holds a reference to "this"
+ return NS_NewStringEnumerator(aResult, mElementNames, this);
+}
+</pre>
+<p>One variant of <code>NS_NewStringEnumerator</code> does not require an owner, but should only be used when the lifetime of the enumerator is known to be shorter than that of the array. Often this is used when a method must take a <code>nsIStringEnumerator</code> rather than an <code>nsStringArray</code>, due to some sort of interface constraint.</p>
+<pre class="eval">class nsFoo : nsIFoo {
+ ...
+ // when ProcessElements returns, the enumerator is at the
+ // end of the list, and can be released.
+ NS_IMETHODIMP ProcessNames(nsIStringEnumerator*);
+ private:
+
+ nsStringArray mElementNames;
+};
+
+...
+nsCOMPtr&lt;nsIStringEnumerator&gt; enumerator;
+NS_NewStringEnumerator(getter_AddRefs(enumerator), mElementNames);
+
+// now call a method on "this" that has a known behavior
+ProcessNames(enumerator);
+// now enumerator is used up, and can be released
+...
+</pre>
+<p>The last version of <code>nsIStringEnumerator</code> takes ownership of an <code>nsStringArray</code> and is responsible for freeing the array when the enumerator is used up.</p>
+<pre class="eval">void GetNames(nsIStringEnumerator** aResult)
+{
+ nsStringArray *resultArray = new nsStringArray;
+ resultArray-&gt;AppendString(str1);
+ resultArray-&gt;AppendString(str2);
+
+ // enumerator will free resultArray
+ return NS_NewAdoptingStringEnumerator(aResult, resultArray);
+}
+</pre>
+<p>As noted above, these implementations of <code>nsIStringEnumerator</code> can also be QueryInterface'd between nsIStringEnumerator and <code>nsIUTF8StringEnumerator</code>. The implementations will properly convert back and forth between UTF8 and Unicode. To ensure that you get the right implementation and the conversion is done in the right direction, make sure that you call the version of <code>NS_NewStringEnumerator</code> or <code>NS_NewUTF8StringEnumerator</code> that corresponds to the array type, not the enumerator type.</p>
+<p>For example, if a class has an internal <code>nsCStringArray</code> of UTF8 strings, but needs to implement an interface which returns an nsIStringEnumerator, it should use <code>NS_NewStringEnumerator</code>:</p>
+<pre class="eval">class nsFoo : nsIFoo {
+ ...
+ NS_IMETHOD GetStrings(nsIStringEnumerator** aResult);
+</pre>
+<pre class="eval"> private:
+ nsCStringArray mElementNames;
+};
+
+NS_IMETHODIMP
+nsFoo::GetStrings(nsIStringEnumerator** aResult) {
+ nsresult rv;
+ nsCOMPtr&lt;nsIUTF8StringEnumerator&gt; enumerator
+ rv = NS_NewUTF8StringEnumerator(getter_AddRefs(enumerator),
+ mElementNames, this);
+ return CallQueryInterface(enumerator, aResult);
+}
+</pre>
+<h2 id="Obsolete_Arrays_and_Enumerators" name="Obsolete_Arrays_and_Enumerators">Obsolete Arrays and Enumerators</h2>
+<h3 id="nsISupportsArray" name="nsISupportsArray">nsISupportsArray</h3>
+<h3 id="nsIEnumerator_.28includes_nsIBidirectionalEnumerator.29" name="nsIEnumerator_.28includes_nsIBidirectionalEnumerator.29">nsIEnumerator (includes nsIBidirectionalEnumerator)</h3>
diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/an_overview_of_xpcom/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/an_overview_of_xpcom/index.html
new file mode 100644
index 0000000000..64bf41704f
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/an_overview_of_xpcom/index.html
@@ -0,0 +1,535 @@
+---
+title: 创建_XPCOM_组件/XPCOM_简介
+slug: Mozilla/Tech/XPCOM/Guide/Creating_components/An_Overview_of_XPCOM
+tags:
+ - XPCOM
+ - 所有分类
+translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/An_Overview_of_XPCOM
+---
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/创建_XPCOM_组件:前言" style="float: left;">« 上一页</a><a href="/zh-CN/docs/创建_XPCOM_组件:使用_XPCOM_组件">下一页 »</a></p>
+</div><p></p>
+
+<p>这是一本关于 XPCOM 的书. 这本书是以编写一个 XPCOM 组件的方式来组织的, 但是这个过程涵盖了 XPCOM 组件模型主要的出发点, 概念和术语.</p>
+
+<p>本章以 XPCOM 的快速导览开始, 简单介绍了 XPCOM 和组件开发的基本概念和技术. 本章的大部分内容从一个很高的角度介绍了这些概念, 这些概念将在创建一个称为 <strong>WebLock</strong> 的 Mozilla 组件过程中逐渐透彻的讲述.</p>
+
+<h3 id="XPCOM_.E8.A7.A3.E5.86.B3.E6.96.B9.E6.A1.88" name="XPCOM_.E8.A7.A3.E5.86.B3.E6.96.B9.E6.A1.88">XPCOM 解决方案</h3>
+
+<p>Cross Platform Component Object Module (XPCOM) 是一个允许开发人员把一个大的工程划分成小的模块的框架. 这些小模块称为<em>组件</em>, 它们在运行时刻组装在一起.</p>
+
+<p>XPCOM 的目标是使软件的不同部分分别开发, 相互独立. 为了是应用的不同组件之间能够互操作, XPCOM 把组件的<em>实现</em>与<em>接口</em>(后面讨论<a href="#接口">接口</a>)分开. 同时 XPCOM 还提供了加载和操纵这些组件的库和工具以及服务, 以帮助开发人员编写跨平台的代码和组件版本管理; 因此组件可以在不破坏应用或者重新生成应用的同时被替换被更新. 通过使用 XPCOM, 开发人员创建的组件可以在不同的应用中被重用, 或者替换当前应用中的组件以改变应用的功能.</p>
+
+<p>XPCOM 不只提供组件软件开发的支持, 它同时提供一个开发平台的大多数功能的支持:</p>
+
+<ul>
+ <li>组件管理</li>
+ <li>文件抽象</li>
+ <li>对象消息传递</li>
+ <li>内存管理</li>
+</ul>
+
+<p>我们将在后面的章节中详细讨论上面的条目, 但是现在, 仅仅把 XPCOM 想象成一个 <em>组件开发平台</em>, 它提供了上面的这些特性.</p>
+
+<h3 id="Gecko" name="Gecko">Gecko</h3>
+
+<p>XPCOM 尽管在许多方面类似于 Microsoft COM, 但 XPCOM 被设计成主要应用于应用层. XPCOM 的最重要的应用是 <em>Gecko</em>, 一个开源的, 遵循标准的, 嵌入式 web 浏览器和 工具包.</p>
+
+<p>XPCOM 是访问 Gecko 库和嵌入或扩展 Gecko 的方法. 本书着重于后者 - 扩展 Gecko - 但是本书中描述的基本思想对嵌入 Gecko 的开发人员也很重要.</p>
+
+<p>Gecko 应用在许多 internet 程序中, 主要是浏览器. 包括 Gateway/AOL Instant AOL device 和 Nokia Media Terminal. Gecko 最近还被应用于的 Compuserve 客户端, AOL for Mac OS X, Netscape 7, 当然还包括 Mozilla 客户端. Gecko 是目前而言主流的开源浏览器.</p>
+
+<h3 id=".E7.BB.84.E4.BB.B6" name=".E7.BB.84.E4.BB.B6">组件</h3>
+
+<p>XPCOM 允许把一个大的工程分解为一些小部分. 这些小部分称为组件, 通常是一些小的可重用的二进制库(在 Windows 下表现为一个 DLL (动态联接库), Unix 下为一个 DSO (分布式共享对象), 这些二进制库可以包含一个或多个组件. 当多个相关组件被封装到一个二进制库, 这个库也称为<em>模块</em>.</p>
+
+<p>把软件划分成不同的组件可以使开发和维护工作变得更容易. 除了这个好处, 模块化组件化的编程还有下面的优势:</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">优点</td>
+ <td class="header">描述</td>
+ </tr>
+ <tr>
+ <td>重用</td>
+ <td>模块化的代码可以在其他应用和环境中被重用.</td>
+ </tr>
+ <tr>
+ <td>更新</td>
+ <td>在不需要重新编译整个应用的情况下更新组件.</td>
+ </tr>
+ <tr>
+ <td>性能</td>
+ <td>代码按照模块化组织, 模块就不必要立刻被加载, 而是以 "lazy" 方式加载, 或者根本不需要加载. 这样就可以提升应用的整体性能.</td>
+ </tr>
+ <tr>
+ <td>维护</td>
+ <td>甚至在不更新组件的情况下, 按照模块化的方式设计应用也能够使你对感兴趣的部分的维护变得更容易.</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Mozilla 有几百万行代码, 没有那个人能够彻底搞明白整个代码的细节. 面对这样的一个系统, 最好的方式是把它划分成一些小的, 更容易管理的部分; 同时使用组件模型来编程, 把相关组件组织到各个模块中去. 比如说, Mozilla 的网络库就包含了 HTTP, FTP, 及其他协议的组件, 这些组件被塞到一个单独的库里. 这个库就是网络模块, 也就是通常所说的 "necko."</p>
+
+<p>但是把事物划分开来并不一定就好, 有许多事物作为一个整体组织起来才是最好的方式, 或者根本就不能划分开来. 比如说, 一个小孩就可能不吃没有果酱的三明志, 对于他来说, 果酱和三明志是缺一不可的整体. 同样的情形也会存在于某些软件中, 某些需要紧耦合的仅仅在内部使用的部分就并不需要费力去把它拆开成为小的模块.</p>
+
+<p>Gecko 中的 HTTP (超文本传输协议)  组件并不会暴露它内部的类, 它是作为一个整体来使用. 组件内部的事物不应该暴露给 XPCOM. 在 Mozilla 早期的开发中, 有些组件的创建并不适当, 但是随着开发的深入, 这些部分会被逐渐移出 XPCOM.</p>
+
+<h3 id=".E6.8E.A5.E5.8F.A3" name=".E6.8E.A5.E5.8F.A3">接口</h3>
+
+<p>把软件划分成组件通常一个好的解决方法, 但是我们该怎么做呢? 基本的思路是按照功能进行划分, 理解这些功能块之间的如何进行通信. 这些组件之间的通信通道就构成了各个组件的边界, 这些边界形式的描述为<em>接口</em>.</p>
+
+<p>接口并不是编程中的一个新的概念. 从我们的第一个 "HelloWorld" 程序开始我们就一直在不知不觉的使用它, 这里的接口就存在于我们的应用程序和打印程序之间. 应用程序使用 <code>stdio</code> 库提供的接口来把 "hello world" 字符串打印到屏幕上. XPCOM 与 "HelloWorld" 程序的不同之处在于 XPCOM 会在运行时刻找到这个屏幕打印的功能, 而 XPCOM 事前根本就不需要在编译的时刻了解 <code>stdio</code> 库提供了什么东西.</p>
+
+<p>接口允许开发人员把功能的具体实现<em>封装</em>在组件内部, 而客户程序不需要了解这个功能是如何实现的, 它只需要使用它就行了.</p>
+
+<div class="side-note">
+<p><span id="%E6%8E%A5%E5%8F%A3%E4%B8%8E%E6%8C%89%E7%85%A7%E5%A5%91%E7%BA%A6(Contract)%E7%BC%96%E7%A8%8B"><a id="%E6%8E%A5%E5%8F%A3%E4%B8%8E%E6%8C%89%E7%85%A7%E5%A5%91%E7%BA%A6(Contract)%E7%BC%96%E7%A8%8B"></a><strong>接口与按照契约(Contract)编程</strong></span></p>
+
+<p>一个接口在组件与客户程序之间达成契约. 并没有任何强制措施保证认同这个契约, 但是忽略它会是致命的. 在基于组件的编程中, 组件保证它提供的接口是<em>不变的</em> - 不同版本的组件都要提供同样的访问方法 - 这就与使用它的客户程序达成了一种契约. 从这种角度来说, 基于组件的编程通常也称为<em>按照契约编程</em>.</p>
+</div>
+
+<h4 id=".E6.8E.A5.E5.8F.A3.E4.B8.8E.E5.B0.81.E8.A3.85" name=".E6.8E.A5.E5.8F.A3.E4.B8.8E.E5.B0.81.E8.A3.85">接口与封装</h4>
+
+<p>组件边界之间的抽象对软件的可维护性与可重用性是致关重要的. 举个例子来说, 考虑下面一个没有很好封装的类. 在下面的例子中, 使用可自由访问的 public 的初始化方法可能会出问题.</p>
+
+<p><span id="SomeClass%E7%B1%BB%E5%88%9D%E5%A7%8B%E5%8C%96"><a id="SomeClass%E7%B1%BB%E5%88%9D%E5%A7%8B%E5%8C%96"></a><strong>SomeClass类初始化</strong></span></p>
+
+<pre>class SomeClass
+{
+ public:
+ // Constructor
+ SomeClass();
+
+ // Virtual Destructor
+ virtual ~SomeClass();
+
+ // init method
+ void Init();
+
+ void DoSomethingUseful();
+};
+</pre>
+
+<p>系统要工作正常, 客户程序员必须注意到组件程序员建立的潜规则. 这就是这个未很好封装的类的契约: 这是一套关于何时该调用一个方法, 调用这个方法之前应该做什么的规则. 这个规则可能指出 <code>DoSomethingUseful</code> 方法只能在调用 <code>Init()</code> 之后被使用. <code>DoSomethingUseful</code> 方法可能会做某些检查工作以保证条件满足 - <code>Init</code> 已经被调用.</p>
+
+<p>除了在代码中给出注释告诉客户程序员关于 <code>Init()</code> 规则之外, 程序员可以使他的契约更明晰. 首先对象的构造函数可以封装起来, 然后向客户程序员提供一个声明 <code>DoSomethingUseful</code> 方法的<em>虚基类</em>. 通过这种方式, 构造函数和初始化函数被隐藏起来. 在这种<em>半封装</em>条件下, 这个类只向客户程序暴露一些良好定义的可调用方法(或者称为接口). 一旦按照这种方式封装一个类, 客户程序只能看到的是下面的接口:</p>
+
+<p><span id="SomeInterface%E5%B0%81%E8%A3%85"><a id="SomeInterface%E5%B0%81%E8%A3%85"></a><strong>SomeInterface封装</strong></span></p>
+
+<pre>class SomeInterface
+{
+ public:
+ virtual void DoSomethingUseful() = 0;
+};
+</pre>
+
+<p>实现类就可以从这个虚基类派生, 实现接口的功能. 客户程序使用类厂(factory pattern)模式来创建对象(参看<a href="#类厂">类厂</a>), 而封装类的内部实现. XPCOM 以这种方式把客户程序屏蔽在组件的内部工作之外, 而客户程序也只依赖于提供所需要功能的接口.</p>
+
+<h4 id="nsISupports_.E5.9F.BA.E6.8E.A5.E5.8F.A3" name="nsISupports_.E5.9F.BA.E6.8E.A5.E5.8F.A3"><code>nsISupports</code> 基接口</h4>
+
+<p>组件与基于接口的编程的两个最基本的问题是: 一个是<em>组件生存期</em>, 也称为<em>对象所属关系</em>; 另一个是<em>接口查询</em>, 它是在运行时刻确定接口能够提供哪些接口. 这一节介绍基接口 <code>nsISupports</code> - 它是 XPCOM 中所有接口的父接口, 它提供了上面两个问题的解决方案.</p>
+
+<h5 id=".E5.AF.B9.E8.B1.A1.E6.89.80.E5.B1.9E.E5.85.B3.E7.B3.BB" name=".E5.AF.B9.E8.B1.A1.E6.89.80.E5.B1.9E.E5.85.B3.E7.B3.BB">对象所属关系</h5>
+
+<p>在 XPCOM 中, 由于组件可以实现任意多的不同接口, 接口必须是<em>引用计数的</em>. 组件在内部跟踪客户程序对它的接口引用了多少次, 当接口计数为零的时候组件就会卸载它自己.</p>
+
+<p>当一个组件创建后, 组件内部有一个整数在跟踪这个引用计数值. 客户程序实例化组件就会自动对这个引用计数加一; 在组件的整个生存期内, 引用计数或加或减, 总是大于零的. 如果在某个时刻, 所有的客户程序对该组件都失去了兴趣, 引用计数减到零, 组件就会卸载自己.</p>
+
+<p>客户程序使用相关接口是一个非常直接的过程. XPCOM 有一些工具让我们更方便的使用接口, 我们会在后面讲述. 如果客户程序在使用接口的时候忘记对接口的引用计数进行相关操作, 就会对组件的维护工作带来某些问题. 此时, 由于组件的引用计数始终不为零, 它就永远不会释放, 从而导致内存泄漏. 引用计数系统就象 XPCOM 的许多其他事物一样, 是客户与组件之间的契约. 如果遵守这些契约, 就会工作得很正常, 反之不然. 由创建接口指针的函数负责对初始化的接口引用加1, 这个引用也称为<em>所属引用</em>.</p>
+
+<div class="side-note">
+<p><span id="XPCOM%E4%B8%AD%E7%9A%84%E6%8C%87%E9%92%88"><a id="XPCOM%E4%B8%AD%E7%9A%84%E6%8C%87%E9%92%88"></a><strong>XPCOM中的指针</strong></span></p>
+
+<p>XPCOM 中的<em>指针</em>术语指的是接口指针. 它与常规指针相比有细微的差别, 毕竟它们都指向的是某个内存区域. 但是 XPCOM 指针指向的都是从 nsISupports 基接口派生而来的接口实现, 这个基接口包括三个基本的方法: <code>AddRef</code>, <code>Release</code>, 和 <code>QueryInterface</code>.</p>
+</div>
+
+<p><code>nsISupports</code> 接口提供了对接口查询与引用计数基本的支持. 这个接口的成员方法包括: <code>QueryInterface</code>, <code>AddRef</code>, 和 <code>Release</code>. 这些方法提供了从一个对象获取正确接口的基本方法, 加引用计数, 释放不再使用的对象. <code>nsISupports</code> 接口的声明如下:</p>
+
+<p><span id="%3Ccode%3EnsISupports%3C/code%3E_%E6%8E%A5%E5%8F%A3"><a id="%3Ccode%3EnsISupports%3C/code%3E_%E6%8E%A5%E5%8F%A3"></a><strong><code>nsISupports</code> 接口</strong></span></p>
+
+<pre>class Sample: public nsISupports
+{
+ private:
+ nsrefcnt mRefCnt;
+ public:
+ Sample();
+ virtual ~Sample();
+
+ NS_IMETHOD QueryInterface(const nsIID &amp;aIID, void **aResult);
+ NS_IMETHOD_(nsrefcnt) AddRef(void);
+ NS_IMETHOD_(nsrefcnt) Release(void);
+};
+</pre>
+
+<p>接口中使用的各种数据类型见<a href="#XPCOM_类型">XPCOM 类型</a>一节. <code>nsISupports</code> 接口的实现代码如下:</p>
+
+<p><span id="%3Ccode%3EnsISupports%3C/code%3E_%E6%8E%A5%E5%8F%A3%E5%AE%9E%E7%8E%B0"><a id="%3Ccode%3EnsISupports%3C/code%3E_%E6%8E%A5%E5%8F%A3%E5%AE%9E%E7%8E%B0"></a><strong><code>nsISupports</code> 接口实现</strong></span></p>
+
+<pre>Sample::Sample()
+{
+ // initialize the reference count to 0
+ mRefCnt = 0;
+}
+Sample::~Sample()
+{
+}
+
+// typical, generic implementation of QI
+NS_IMETHODIMP Sample::QueryInterface(const nsIID &amp;aIID,
+ void **aResult)
+{
+ if (aResult == NULL) {
+ return NS_ERROR_NULL_POINTER;
+ }
+ *aResult = NULL;
+ if (aIID.Equals(kISupportsIID)) {
+ *aResult = (void *) this;
+ }
+ if (*aResult == NULL) {
+ return NS_ERROR_NO_INTERFACE;
+ }
+ // add a reference
+ AddRef();
+ return NS_OK;
+}
+
+NS_IMETHODIMP_(nsrefcnt) Sample::AddRef()
+{
+ return ++mRefCnt;
+}
+
+NS_IMETHODIMP_(nsrefcnt) Sample::Release()
+{
+ if (--mRefCnt == 0) {
+ delete this;
+ return 0;
+ }
+ // optional: return the reference count
+ return mRefCnt;
+}
+</pre>
+
+<h5 id=".E5.AF.B9.E8.B1.A1.E6.8E.A5.E5.8F.A3.E7.9A.84.E5.8F.91.E7.8E.B0" name=".E5.AF.B9.E8.B1.A1.E6.8E.A5.E5.8F.A3.E7.9A.84.E5.8F.91.E7.8E.B0">对象接口的发现</h5>
+
+<p><em>继承</em>是面向对象编程中另一个非常重要的话题. 继承是通过一个类派生另一个类的方法. 当一个类继承另一个类, 继承类可以<em>重载</em>基类的缺省动作, 而不需要拷贝基类的代码, 从而创建更加专有的类. 如下所示:</p>
+
+<p><span id="%E7%AE%80%E5%8D%95%E7%B1%BB%E7%BB%A7%E6%89%BF"><a id="%E7%AE%80%E5%8D%95%E7%B1%BB%E7%BB%A7%E6%89%BF"></a><strong>简单类继承</strong></span></p>
+
+<pre>class Shape
+{
+ private:
+ int m_x;
+ int m_y;
+
+ public:
+ virtual void Draw() = 0;
+ Shape();
+ virtual ~Shape();
+};
+
+class Circle : public Shape
+{
+ private:
+ int m_radius;
+ public:
+ virtual Draw();
+ Circle(int x, int y, int radius);
+ virtual ~Circle();
+};
+</pre>
+
+<p><code>Circle</code> 从 <code>Shape</code> 类派生. <code>Circle</code> 本身也是一个 <code>Shape</code>, 但是 <code>Shape</code> 并不一定是 <code>Circle</code>. 在这种情况下, <code>Shape</code> 是<em>基类</em>, <code>Circle</code> 是 <code>Shape</code> 的子类.</p>
+
+<p>在 XPCOM 中, 所有的类都派生自 <code>nsISupports</code> 接口, 这样所有的对象都提供 <code>nsISupports</code>接口, 但是这些对象是更专有的类, 在运行时刻必须能找到它. 比如说在<a href="#简单类继承">简单类继承</a>例子中, 如果对象是一个 <code>Circle</code>, 你就可以调用 <code>Shape</code> 类的方法. 就是为什么在 XPCOM 中, 所有的对象都派生自 <code>nsISupports</code> 接口: 它允许客户程序根据需要发现和访问不同的接口.</p>
+
+<p>在 C++ 中, 我们可以使用 <code>dynamic_cast&lt;&gt;</code> 来把一个 <code>Shape</code> 对象的指针强制转化成一个 <code>Circle</code> 指针, 如果不能转化就抛出异常. 但是在 XPCOM 中, 由于性能开销和平台兼容性问题, 采用 RTTI (运行时刻类型信息) 的方法是不行的.</p>
+
+<div class="side-note">
+<p><span id="XPCOM_%E4%B8%AD%E7%9A%84%E5%BC%82%E5%B8%B8"><a id="XPCOM_%E4%B8%AD%E7%9A%84%E5%BC%82%E5%B8%B8"></a><strong>XPCOM 中的异常</strong></span></p>
+
+<p>XPCOM 并不直接支持 C++ 的异常处理. 在 XPCOM 中, 所有的异常必须在组件内部处理, 而不能跨越接口的边界. 然后接口方法返回一个 <code>nsresult</code> 错误值(这些错误码请参考 <a href="/cn/XPCOM_API_Reference" title="cn/XPCOM_API_Reference">XPCOM API Reference</a>). 客户程序根据这些错误码进行"异常"处理.</p>
+</div>
+
+<p>XPCOM 没有采用 C++ RTTI 机制来实现对象指针的动态转化, 它使用 <code>QueryInterface</code> 方法来把一个对象指针 cast 成正确的接口指针.</p>
+
+<p>每个接口使用称为 "uuidgen" 的工具来生成专有ID. 这个 ID 是一个全局唯一的 128-bit 值. 在接口的语境中, 这个 ID 又称为 <em>IID</em>. (组件语境中, 这个 ID 代表的是一个契约)</p>
+
+<p>当客户程序想查询一个对象是否支持某个接口, 它把接口的 IID 值传递给这个对象的 <code>QueryInterface</code> 方法. 如果对象支持这个接口, 它就会对自己的引用计数加1, 然后返回指向那个专有接口的指针. 反之, 如果不支持这个接口, 它会返回一个错误码.</p>
+
+<pre>class nsISupports {
+ public:
+ long QueryInterface(const nsIID &amp; uuid,
+ void **result) = 0;
+ long AddRef(void) = 0;
+ long Release(void) = 0;
+};
+</pre>
+
+<p><code>QueryInterface</code> 的第一个参数是一个 <code>nsIID</code> 类型的引用, 它封装了 IID. <code>nsIID</code> 类有三种方法: <code>Equals</code>, <code>Parse</code>, 和 <code>ToString</code>. <code>Equals</code> 在接口查询中是最重要的, 它用来比较两个 <code>nsIID</code> 对象是否相同.</p>
+
+<p>在客户以 IID 调用 <code>nsISupports</code> 接口的 <code>QueryInterface</code> 方法时, 我们必须保证返回一个有效的 result 参数(在<a href="/cn/Creating_XPCOM_Components/Using_XPCOM_Utilities_to_Make_Things_Easier" title="cn/Creating_XPCOM_Components/Using_XPCOM_Utilities_to_Make_Things_Easier">Using XPCOM Utilities to Make Things Easier</a> 一章中, 我们将看到怎样更方便的实现一个 <code>nsIID</code> 类). <code>QueryInterface</code> 方法应该支持该组件所有接口的查询.</p>
+
+<p>在 <code>QueryInterface</code> 方法的实现中, IID 参数与组件支持 <code>nsIID</code> 类进行比较. 如果匹配, 对象的 <code>this</code> 指针转化为 <code>void</code> 指针, 引用计数加1, 把 <code>void</code> 指针返回给客户程序.</p>
+
+<p>在上面的例子中, 仅仅使用 C 方式的类型转化就足够了. 但是在把 <code>void</code> 指针 cast 成接口指针的时候, 还有更多的问题, 因为返回的接口指针必须与 vtable (virtual table) 相对应. 当出现菱形多重继承的时候, 可能这种接口转化就会有问题.</p>
+
+<h3 id="XPCOM_.E7.9A.84ID" name="XPCOM_.E7.9A.84ID">XPCOM 的ID</h3>
+
+<p>除了上一节中的接口 IID, XPCOM 还使用两种 ID 来区分类与组件.</p>
+
+<div class="side-note">
+<p><span id="XPCOM_ID%E7%B1%BB"><a id="XPCOM_ID%E7%B1%BB"></a><strong>XPCOM ID类</strong></span></p>
+
+<p><code>nsIID</code> 类实际上是一种 <code>nsID</code> 类. 其他的 <code>nsID</code>, CID 和 IID, 分别指的是一个实体类和一个专有的接口.</p>
+
+<p><code>nsID</code> 类提供 <code>Equals</code> 类似的方法, 来比较 ID. 请参考 <a href="/cn/Creating_XPCOM_Components/Creating_the_Component_Code#Identifiers_in_XPCOM" title="cn/Creating_XPCOM_Components/Creating_the_Component_Code#Identifiers_in_XPCOM">Identifiers in XPCOM</a> 一节, 其中对 <code>nsID</code> 类有更多的讨论.</p>
+</div>
+
+<h4 id="CID" name="CID">CID</h4>
+
+<p>CID 是一个唯一的 128-bit 值, 类似于 IID, 它用于全局标识唯一的类或者组件. <code>nsISupports</code> 的 CID 就象:</p>
+
+<p><code>00000000-0000-0000-c000-000000000046</code></p>
+
+<p>由于 CID 比较长, 通常我们都使用#define来定义它:</p>
+
+<pre>#define SAMPLE_CID \
+{ 0x777f7150, 0x4a2b, 0x4301, \
+{ 0xad, 0x10, 0x5e, 0xab, 0x25, 0xb3, 0x22, 0xaa}}
+</pre>
+
+<p>我们将会看到许多 <code>NS_DEFINE_CID</code> 的定义. 下面的宏用 CID 定义了一个静态变量:</p>
+
+<pre>static NS_DEFINE_CID(kWebShellCID, NS_WEB_SHELL_CID);
+</pre>
+
+<p>CID 有时也称为<em>类 ID</em>. 如果一个类实现了多个接口, 当CID 在该类发布后, 就与该类的 IID 一起被冻结了.</p>
+
+<h4 id=".E5.A5.91.E7.BA.A6_ID" name=".E5.A5.91.E7.BA.A6_ID">契约 ID</h4>
+
+<p>契约 ID 是一个用于访问组件的可读(to humen)的字符串. 一个 CID 或者一个契约 ID 可以用于从一个组件管理器获取组件. 下面是一个用于 LDAP 操作组件的契约 ID:</p>
+
+<pre>"@mozilla.org/network/ldap-operation;1"
+</pre>
+
+<p>契约 ID 的格式是: 用斜杠分开的组件的<em>域</em>, <em>模块</em>, <em>组件名</em>, <em>版本号</em>.</p>
+
+<p>与 CID 类似, 契约 ID 指的是组件实现而不是接口. 但是契约 ID 并不像CID那样,被限定为某个专有实现, 它更通用. 一个契约 ID 只是指明需要实现的一组接口,可以通过任意数量的CID满足这个需要. 契约 ID 与 CID 的这种不同, 使得组件重写成为可能.</p>
+
+<h3 id=".E7.B1.BB.E5.8E.82" name=".E7.B1.BB.E5.8E.82">类厂</h3>
+
+<p>把代码划分成组件, 客户代码通常使用 <code>new</code> 操作符来构造实例对象:</p>
+
+<pre>SomeClass* component = new SomeClass();
+</pre>
+
+<p>这种模式或多或少地需要客户对组件有一定的了解,至少要知道组件的大小. <em>类厂设计模式</em>此时可以用来封装对象的构造过程. 类厂模式的目的是在不暴露对象的实现和初始化的前提下创建对象. 在 <code>SomeClass</code> 例子中, 可以按照类厂模式把 <code>SomeClass</code> 对象的构造和初始化封装在 <code>New_SomeInterface</code> 函数中:</p>
+
+<p><span id="%E5%B0%81%E8%A3%85%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0"><a id="%E5%B0%81%E8%A3%85%E6%9E%84%E9%80%A0%E5%87%BD%E6%95%B0"></a><strong>封装构造函数</strong></span></p>
+
+<pre>int New_SomeInterface(SomeInterface** ret)
+{
+ // create the object
+ SomeClass* out = new SomeClass();
+ if (!out) return -1;
+
+ // init the object
+ if (out-&gt;Init() == FALSE)
+ {
+ delete out;
+ return -1;
+ }
+
+ // cast to the interface
+ *ret = static_cast&lt;SomeInterface*&gt;(out);
+ return 0;
+}
+</pre>
+
+<p>类厂本身是一个管理组件实例化的类. 在 XPCOM 中, 类厂要实现 <code>nsIFactory</code> 接口, 它们就象上面的代码一样要使用类厂设计模式来封装对象的构造和初始化.</p>
+
+<p><a href="#封装构造函数">封装构造函数</a> 的例子是一个简单的无状态的类厂版本, 实际的编程要复杂一些, 一般的类厂都需要保存状态. 类厂至少应该保存那些对象已经被创建了的信息. 如果类厂管理的实例被存放在一个动态联接库中, 还需要知道什么时候可以卸载这个动态联接库. 当类厂保存了这样的信息, 就可以向类厂查询一个对象是否已经被创建.</p>
+
+<p>另一个需要保存的信息是关于<em>单件(singleton)</em>. 如果一个类厂已经创建了一个单件类型的类, 后续的创建该单件的函数调用将返回已经创建的对象. 尽管有更好的工具和方式来管理单件(在讨论 <code>nsIServiceManager</code> 会看到), 开发人员可能仍然需要通过这种方式来保证只有一个单件对象被创建.</p>
+
+<p>厂模式可以完全利用函数来做, 状态可以保存在全局变量中; 但是使用类的方式来实现厂模式还有更多的好处. 其一是: 我们可以管理从 <code>nsISupports</code> 接口派生而来的类厂本身的生存期. 当我们试图把多个类厂划分成一组, 然后确定是否能卸载这一组类厂的时候, 这一点非常重要. 另一个好处是: 类厂可以引入其他需要支持的接口. 在我们后面讨论 <code>nsIClassInfo</code> 接口的时候, 我们会看到某些类厂使用这个接口支持信息查询, 诸如这个对象是用什么语言写的, 对象支持的接口等等. 这种派生自 <code>nsISupports</code> 的 "future-proofing" 特性非常关键.</p>
+
+<h4 id="XPIDL_.E4.B8.8E.E7.B1.BB.E5.9E.8B.E5.BA.93" name="XPIDL_.E4.B8.8E.E7.B1.BB.E5.9E.8B.E5.BA.93">XPIDL 与类型库</h4>
+
+<p>定义接口的简单而强劲的方法是使用<em>接口定义语言</em>(IDL) - 这实际上是在一个跨平台而语言无关开发环境下定义接口的需求. XPCOM 使用的是源自于 CORBA OMG 接口定义语言(IDL)的变体, 称为 XPIDL, 来定义接口, XPIDL 可以定义接口的方法, 属性, 常量, 以及接口继承.</p>
+
+<p>采用 XPIDL 定义接口还存在一些缺陷. 它不支持多继承, 同时 XPIDL 定义的方法名不能相同,你不能有两个相同名字但是所接受的参数不同的函数. - 不能像 C++ 语言的成员函数一样通过参数不同重载, 毕竟接口同时要支持类似于 C 这样的语言.</p>
+
+<pre>void FooWithInt(in int x);
+void FooWithString(in string x);
+void FooWithURI(in nsIURI x);
+</pre>
+
+<p>然而尽管有这些问题, XPIDL 的功能仍然是非常强大的. XPIDL 能自动生成以 <em>.xpt</em> 为后缀的<em>类型库</em>, 或者说 typelibs. 类型库是接口的二进制表示, 它向非 C++ 语言提供接口的访问与控制. 非 C++ 语言通过类型库来了解接口支持哪些方法, 如何调用这些方法, 这称为 <em>XPConnect</em>. XPConnect 是 XPCOM 向类似于 JavaScript 这样的语言提供组件访问的 Wrapper. 参看<a href="/cn/Creating_XPCOM_Components/Using_XPCOM_Components#Connecting_to_Components_from_the_Interface" title="cn/Creating_XPCOM_Components/Using_XPCOM_Components#Connecting_to_Components_from_the_Interface">Connecting to Components from the Interface</a>获取更多关于 XPConnect 的信息.</p>
+
+<p>从其他类型的语言访问接口, 常常说成是接口被<em>反射(reflected)</em>到这种语言. 每一个被反射的接口必须提供相应的类型库. 当前可以使用 C, C++, 和 JavaScript 来编写组件.</p>
+
+<div class="side-note">
+<p><span id="%E4%BD%BF%E7%94%A8%E5%85%B6%E4%BB%96%E8%AF%AD%E8%A8%80%E7%BC%96%E5%86%99%E7%BB%84%E4%BB%B6"><a id="%E4%BD%BF%E7%94%A8%E5%85%B6%E4%BB%96%E8%AF%AD%E8%A8%80%E7%BC%96%E5%86%99%E7%BB%84%E4%BB%B6"></a><strong>使用其他语言编写组件</strong></span></p>
+
+<p>在使用其他语言创建组件的时候, 不需要利用 XPCOM 提供给 C++ 程序员的工具(诸如一些宏, 智能指针等等, 我们可以方便的利用到这种语言本身来创建组件. 比如说, 基于 Python 的 XPCOM 组件可以从 JavaScript 来调用.</p>
+
+<p>参看 <a href="/cn/Creating_XPCOM_Components/Resources" title="cn/Creating_XPCOM_Components/Resources">Resources</a> 获取更多使用其他语言来创建组件的信息.</p>
+</div>
+
+<p>所有的 XPCOM 接口都用 XPIDL 语法来定义. <em>xpidl 编译器</em>会从这个 IDL 文件产生类型库和 C++ 头文件. 在<a href="/cn/Creating_XPCOM_Components/Starting_WebLock#Defining_the_WebLock_Interface_in_XPIDL" title="cn/Creating_XPCOM_Components/Starting_WebLock#Defining_the_WebLock_Interface_in_XPIDL">Defining the WebLock Interface in XPIDL</a> 一节详细描述了 XPIDL 语法.</p>
+
+<h3 id="XPCOM_.E6.9C.8D.E5.8A.A1" name="XPCOM_.E6.9C.8D.E5.8A.A1">XPCOM 服务</h3>
+
+<p>当客户需要某个组件提供的功能的时候, 通常都是<em>实例化</em>一个新的组件对象. 比如说, 客户程序需要某些处理文件, 这里每个组件就代表一个文件, 客户可能会同时处理多个这样的组件.</p>
+
+<p>但是在某些情况下对象表示的是一种<em>服务</em>, 这种服务只能有一个拷贝(尽管会有多个服务同时运行). 每次客户程序访问服务提供的功能时, 客户程序都是与同一个服务实例在打交道. 比如说, 一个用户查询公司的电话号码数据库, 数据库作为一个<em>对象</em>对用户来说都是同一的. 如若不然的话, 就需要维护两个数据库拷贝, 这种开销将非常大, 而且还存在数据内容不一致的问题. 单件设计模式就是提供系统中需要的这种单点访问功能.</p>
+
+<p>XPCOM 不仅提供了对组件的支持和管理服务, 它还包含了许多编写跨平台组件所需要的其他服务. 其中包括: 跨平台文件抽象, 向 XPCOM 开发人员提供同一而强大的文件访问功能. 目录服务, 提供应用和特定系统定位信息. 内存管理, 保证所有对象使用同样的内存分配器. 事件通知机制, 允许传递简单消息. 本教程将在后面展现如何使用这些服务, <a href="/cn/XPCOM_API_Reference" title="cn/XPCOM_API_Reference">XPCOM API Reference</a> 一节有完整的接口索引列表.</p>
+
+<h3 id="XPCOM_.E7.B1.BB.E5.9E.8B" name="XPCOM_.E7.B1.BB.E5.9E.8B">XPCOM 类型</h3>
+
+<p>XPCOM 声明了许多数据类型和简单宏, 这些东西将在我们后面的例子中看到. 大多数的宏都是简单的重定义, 下一节我们会描述一些最常用的数据类型.</p>
+
+<h4 id=".E6.96.B9.E6.B3.95.E7.B1.BB.E5.9E.8B" name=".E6.96.B9.E6.B3.95.E7.B1.BB.E5.9E.8B">方法类型</h4>
+
+<p>下面的类型用在 XPCOM 方法调用的参数和返回值定义中.</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>NS_IMETHOD</code></td>
+ <td>声明方法返回值. XPCOM 的方法缺省的返回值声明.</td>
+ </tr>
+ <tr>
+ <td><code>NS_IMETHODIMP</code></td>
+ <td>方法实现返回值. XPCOM 方法函数返回的时候缺省采用这种类型的返回值.</td>
+ </tr>
+ <tr>
+ <td><code>NS_IMETHODIMP_(type)</code></td>
+ <td>特定类型的方法实现返回值. 诸如 <code>AddRef</code> 和 <code>Release</code> 的方法不返回缺省类型, 这种返回值的不一致虽然有点不舒服, 但是必需的.</td>
+ </tr>
+ <tr>
+ <td><code>NS_IMPORT</code></td>
+ <td>共享库内部使用的符号局部声明</td>
+ </tr>
+ <tr>
+ <td><code>NS_EXPORT</code></td>
+ <td>共享库导出的符号声明.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h4 id=".E5.BC.95.E7.94.A8.E8.AE.A1.E6.95.B0" name=".E5.BC.95.E7.94.A8.E8.AE.A1.E6.95.B0">引用计数</h4>
+
+<p>下面的宏提供对引用计数的基本操作.</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>NS_ADDREF</code></td>
+ <td>调用 <code>nsISupports</code> 对象的 <code>AddRef</code> 方法.</td>
+ </tr>
+ <tr>
+ <td><code>NS_IF_ADDREF</code></td>
+ <td>与上一个方法类似, 不同之处在于这个宏在<code>AddRef之前</code>会检查对象指针是否为空(虚函数指针).</td>
+ </tr>
+ <tr>
+ <td><code>NS_RELEASE</code></td>
+ <td>调用 <code>nsISupports</code> 对象的 <code>Release</code> 方法.</td>
+ </tr>
+ <tr>
+ <td><code>NS_IF_RELEASE</code></td>
+ <td>与上一个方法类似, 不同之处在于这个宏<code>在调用Release</code>之前会检查空指针.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id=".E7.8A.B6.E6.80.81.E7.A0.81" name=".E7.8A.B6.E6.80.81.E7.A0.81">状态码</h3>
+
+<p>下面的宏测试状态码.</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>NS_FAILED</code></td>
+ <td>如果传递的状态码为失败, 则返回真.</td>
+ </tr>
+ <tr>
+ <td><code>NS_SUCCEEDED</code></td>
+ <td>如果传递的状态码为成功, 则返回真.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id=".E5.8F.98.E9.87.8F.E6.98.A0.E5.B0.84" name=".E5.8F.98.E9.87.8F.E6.98.A0.E5.B0.84">变量映射</h3>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>nsrefcnt</code></td>
+ <td>缺省的引用计数类型, 是一个 32-bit 整数.</td>
+ </tr>
+ <tr>
+ <td><code>nsresult</code></td>
+ <td>缺省数据类型, 是一个 32-bit 整数.</td>
+ </tr>
+ <tr>
+ <td><code>nsnull</code></td>
+ <td>缺省 null 类型.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id=".E9.80.9A.E7.94.A8_XPCOM_.E9.94.99.E8.AF.AF.E7.A0.81" name=".E9.80.9A.E7.94.A8_XPCOM_.E9.94.99.E8.AF.AF.E7.A0.81">通用 XPCOM 错误码</h3>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>NS_ERROR_NOT_INITIALIZED</code></td>
+ <td>如果实例未初试化, 返回该值.</td>
+ </tr>
+ <tr>
+ <td><code>NS_ERROR_ALREADY_INITIALIZED</code></td>
+ <td>如果实例已初试化, 返回该值.</td>
+ </tr>
+ <tr>
+ <td><code>NS_ERROR_NOT_IMPLEMENTED</code></td>
+ <td>如果方法未实现, 返回该值.</td>
+ </tr>
+ <tr>
+ <td><code>NS_ERROR_NO_INTERFACE</code></td>
+ <td>如果组件不支持某种类型接口, 返回该值.</td>
+ </tr>
+ <tr>
+ <td><code>NS_ERROR_NULL_POINTER</code></td>
+ <td>如果指针指向 <code>nsnull</code>, 返回该值 .</td>
+ </tr>
+ <tr>
+ <td><code>NS_ERROR_FAILURE</code></td>
+ <td>如果某个方法失效, 返回该值, 这时一个通用的错误值.</td>
+ </tr>
+ <tr>
+ <td><code>NS_ERROR_UNEXPECTED</code></td>
+ <td>如果一个未预料的错误发生, 返回该值.</td>
+ </tr>
+ <tr>
+ <td><code>NS_ERROR_OUT_OF_MEMORY</code></td>
+ <td>如果无法进行内存分配, 返回该值.</td>
+ </tr>
+ <tr>
+ <td><code>NS_ERROR_FACTORY_NOT_REGISTERED</code></td>
+ <td>如果一个请求的类型未注册, 返回该值.</td>
+ </tr>
+ </tbody>
+</table>
+
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/创建_XPCOM_组件:前言" style="float: left;">« 上一页</a><a href="/zh-CN/docs/创建_XPCOM_组件:使用_XPCOM_组件">下一页 »</a></p>
+</div> <p></p><div class="licenseblock">
+<p>Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the <a class="external" href="http://www.opencontent.org/openpub/" rel="noopener">Open Publication License</a>, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.</p>
+</div><p></p>
+
+<p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/building_the_weblock_ui/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/building_the_weblock_ui/index.html
new file mode 100644
index 0000000000..51f544fb16
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/building_the_weblock_ui/index.html
@@ -0,0 +1,297 @@
+---
+title: Building the WebLock UI
+slug: Mozilla/Tech/XPCOM/Guide/Creating_components/Building_the_WebLock_UI
+tags:
+ - XPCOM
+ - 所有分类
+translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/Building_the_WebLock_UI
+---
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/Creating_XPCOM_Components:Finishing_the_Component" style="float: left;">« 上一页</a><a href="/zh-CN/docs/Creating_XPCOM_Components:Packaging_WebLock">下一页 »</a></p>
+</div><p></p>
+
+<p>到目前为止我们建立了一个可以安装到Gecko应用中的组件。你所使用的XPCOM接口和工具是通用的跨平台的,可以被Gecko Runtime Environment或者任何Mozilla1.2以后任何基于Gecko的应用(这时GRE已经可用)。</p>
+
+<p>本章,我们将建立<strong>WebLock</strong>组件的用户接口,这就意味着添加到<em>现有的</em> Mozilla 浏览器<sup><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Guide/Creating_components/Building_the_WebLock_UI#endnote_other-mozlike-browsers">[other-mozlike-browsers]</a></sup>. 他使用 <abbr title="XML UI Language">XUL</abbr>, 这是一个Gecko知道如何呈现用户界面的XML语言, 同时它也跟特定的Mozilla用户界面交互, 为此它要把自己作为UI的扩展安装起来. Specifically, the user interface we create in this chapter will be<em>overlaid</em> into the statusbar of the browser component, where it will provide a small icon the user can click to access the web lock interface.</p>
+
+<p><span id="WebLock_Indicator_in_Browser"><a id="WebLock_Indicator_in_Browser"></a><strong>WebLock Indicator in Browser</strong></span></p>
+
+<p><img alt="Image:web-lock-ui.png"></p>
+
+<h3 id="User_Interface_Package_List" name="User_Interface_Package_List">User Interface Package List</h3>
+
+<p>本章所描述的用户界面包括4个文件:</p>
+
+<ul>
+ <li><code>webLockOverlay.xul</code> is the file that defines the little status icon in the browser.</li>
+ <li><code>weblock.xul</code> defines the web lock manager dialog.</li>
+ <li><code>weblock.css</code> provides style rules for both of the XUL files.</li>
+ <li><code>weblock.js</code> provides JavaScript functions for both of the XUL files.</li>
+</ul>
+
+<p>下面章节描述每个文件的功能。. In the following chapter we'll describe how you can take these files and create a<em>package</em> , an installable archive that includes the <strong>WebLock</strong> component and the new UI.</p>
+
+<p>因为这些步骤 (特别是 overlay section) 与Mozilla非常相关, the chapter is divided up into a couple of different sections. 第二部分, <a href="#XUL">XUL</a>, 描述XML-based 用户接口语言 (XUL) 以及他如何创建一个对话框访问<strong>WebLock</strong> 组件和它的服务. 第三部分, <a href="#Overlaying_New_User_Interface_Into_Mozilla">Overlaying New User Interface Into Mozilla</a>, 描述如何建立一个overlay到浏览器以便Mozilla build能访问这个对话框. 在overlay section, 我们讨论如何从Mozilla导入scripts, images, 和其他资源到你的 UI, 这会是比较复杂的部分.</p>
+
+<p>If the <strong>WebLock</strong> component is being installed in Mozilla or another Gecko-based browser, then this third section shows you how to create the entry point in the browser for controlling the web locking. If you are planning on deploying the <strong>WebLock</strong> component in some other application, you'll have to devise a different means of access (e.g., native widgetry that instantiates and controls the <strong>WebLock</strong> component).</p>
+
+<h3 id="Client_Code_Overview" name="Client_Code_Overview">Client Code Overview</h3>
+
+<p>在我们开始实际用户界面以前,我们应该首先建立访问<strong>WebLock</strong>组件和它的接口来控制browser的Web locking的客户代码.</p>
+
+<p>首先, it's important to be able to 表达Lock的基本状态as soon as it's loaded. 如同安全网页icon, weblock icon 在browser右下角,提示browser是否当前是锁定的. Since the <strong>WebLock</strong> component is always initialized as unlocked, we can have the 客户代码 - 接口中的JavaScript代码 - 表达并跟踪状态 as the user manipulates the <code>iWebLock</code> interface. A boolean <code>wLocked</code> variable can do this:</p>
+
+<pre>// initialize the wLocked variable as unlocked
+var wLocked = 0;
+</pre>
+
+<p>Then the functions that get called from the interface and call through to the <code>lock</code> and <code>unlock</code> methods of the <strong>WebLock</strong> component must also adjust this variable accordingly:</p>
+
+<pre>function wLock()
+{
+ // check to see if locking is on or off
+ weblock.lock();
+ wLocked = 1;
+}
+
+function wUnLock()
+{
+ // check to see if locking is on or off
+ weblock.unlock();
+ wLocked = 0;
+}
+</pre>
+
+<p>这些函数的前提是<strong>WebLock</strong> 组件对于 JavaScript可见,in the form of the <code>weblock</code> object being used in the snippets above. As you can see, <code>weblock</code> is initialized as a global JavaScript variable, available in the scope of these functions and others:</p>
+
+<pre>var weblock = Components.classes["@dougt/weblock"]
+ .getService()
+ .QueryInterface(Components.interfaces.iWebLock);
+</pre>
+
+<p>In addition to this basic setup, you must also write JavaScript that uses the <code>AddSite</code> method to add new sites to the white list. This is a bit more complicated, because it requires that you work with the currently loaded page or provide other UI (e.g., a textfield where you can enter an arbitrary URL) for specifying URLs. In the <a href="#XUL">XUL</a> section we'll go into how the user interface is defined. This section describes the functions that are called from the interface and how they interact with the <strong>WebLock</strong> component.</p>
+
+<p>The URL that the <code>AddSite</code> method expects is a string, so we can pass a string directly in from the user interface, or we can do a check on the string and verify that it's a valid URL. In this tutorial, focusing as it is on the <strong>WebLock</strong> functionality (rather than the UI), we'll assume the strings we get from the UI itself are URLs we actually want to write to the white list:</p>
+
+<pre>function addThisSite()
+{
+ var tf = document.getElementById("dialog.input");
+ // weblock is global and declared above
+ weblock.AddSite(tf.value);
+}
+</pre>
+
+<p>这段javascript可以直接被 XUL widget调用, where the input string is retrieved as the <code>value</code> property of the <code>textbox</code> element.</p>
+
+<p>你还需要建立一个函数当用户点击weblock icon的时候来显示<strong>WebLock</strong> 窗口. That function uses the <code>openDialog</code> method from the <code>window</code> object and takes the URL to the XUL file in which the dialog is defined:</p>
+
+<pre>function loadWebLock()
+{
+ window.openDialog("chrome://weblock/weblock.xul");
+}
+</pre>
+
+<h3 id="XUL" name="XUL">XUL</h3>
+
+<p>The entire user interface of the Mozilla browser and all of the applications that go with it, including the mail client, the IRC client, and others, have been defined in an XML language called XUL. Elements in the XUL markup map to widgets in the interface that Gecko renders in a fairly straightforward way - so, for instance, the root element of an application window is the element <code>&lt;window/&gt;</code>, the root element of the dialog we'll be creating here is <code>&lt;dialog/&gt;</code>, and so forth. Within a XUL application file, elements like <code>&lt;button/&gt;</code>, <code>menu/&gt;</code>, and <code>checkbox/&gt;</code> can be hooked up to an event model, to scripts, and to the XPCOM interfaces that carry out a lot of the browser functionality in Mozilla.</p>
+
+<p>In <a href="cn/Creating_XPCOM_Components/Using_XPCOM_Components">Using XPCOM Components</a> you saw how XPCOM objects are reflected into the interface layer as JavaScript objects. In this chapter, now that we've created the <strong>WebLock</strong> component and made it available to XPCOM, we create the UI that actually instantiates the <strong>WebLock</strong> component and uses its methods to control page loading in the browser.</p>
+
+<p>In the previous section, we outlined the JavaScript that interacts with the <strong>WebLock</strong> component. In this section, we are going to create the XUL interface that calls the JavaScript methods when the user interacts with it.</p>
+
+<h4 id="The_XUL_Document" name="The_XUL_Document">The XUL Document</h4>
+
+<p>The first thing to do is create the actual XUL document in which the user interface for the dialog and the events that initiate interaction with the web locking are defined. At the top of all XUL documents, an XML declaration is followed by the root element for the document, which is usually <code>&lt;window/&gt;</code> 对于对话框,也可以是<code>&lt;dialog/&gt;</code>. The "shell" for the XUL file, then, looks like this:</p>
+
+<pre>&lt;?xml version="1.0"?&gt;
+&lt;?xml-stylesheet href="chrome://global/skin/" type="text/css"?&gt;
+
+&lt;dialog id="weblock_ui"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="Web Lock Manager"
+ persist="screenX screenY"
+ screenX="24" screenY="24"&gt;
+
+&lt;/dialog&gt;
+</pre>
+
+<p>注意这部分XUL文件也包含了stylesheet declaration, which imports CSS rules and applies them to particular parts of the interface. In Gecko, CSS 被用来几乎控制所有的XUL界面表现 - its color, position, style, and to some extent its behavior as well. The web lock manager dialog does not deviate from the look of a standard dialog, so it can use a single declaration to import the "global" skin from the browser and make it available to the widgets you define in <code>weblock.xul</code>.</p>
+
+<p>You can save this first, 最外层的web lock dialog部分称为<code>weblock.xul</code>, 你要把它放在附录B所描述的安装包里.</p>
+
+<div class="side-note">
+<p>注意这个文件包含了当用户/管理员点击web locking icon的时候弹出的对话框. 这部分UI - 需要动态地装载到Mozilla runtime - 在<a href="#Overlaying_New_User_Interface_Into_Mozilla">Overlaying New User Interface Into Mozilla</a>.</p>
+</div>
+
+<p>描述</p>
+
+<p>最终的对话框看起来是.</p>
+
+<p><span id="Web_Lock_Manager_Dialog"><a id="Web_Lock_Manager_Dialog"></a><strong>Web Lock Manager Dialog</strong></span></p>
+
+<p><img alt="Image:Weblock-sitelist-ui.png"></p>
+
+<p>As you can see, it's a simple interface, providing just enough widgetry to lock and unlock the browser and to add new sites to the list. The entire XUL file for the web lock manager dialog is defined in <a href="#weblock.xul">weblock.xul</a> below.</p>
+
+<h4 id="The_Locking_UI" name="The_Locking_UI">The Locking UI</h4>
+
+<p>Once you have the basic XUL wrapper set up for your interface, the next step is to define that part of the interface that locks and unlocks the browser. One of the most efficient ways to expose this is to use radio buttons, which allow the user to toggle a particulart state, as the figure above illustrates.</p>
+
+<p>In XUL individual <code>&lt;radio/&gt;</code> elements are contained within a parent element called <code>&lt;radiogroup/&gt;</code>. Grouping radio elements together creates the toggling UI by requiring that one or another of the elements be selected, but not both.</p>
+
+<p>The XUL that defines the radiogroup in the web lock manager dialog is this:</p>
+
+<pre>&lt;radiogroup&gt;
+ &lt;radio label="lock"/&gt;
+ &lt;radio label="unlock" selected="true"/&gt;
+&lt;/radiogroup&gt;
+</pre>
+
+<p>Since the <strong>WebLock</strong> component always starts up in the unlocked position, you can add the <code>selected="true"</code> attribute and value on the unlock radio button and reset it dynamically as the user takes action.</p>
+
+<h4 id="Site_Adding_UI" name="Site_Adding_UI">Site Adding UI</h4>
+
+<p>The next step is to create that part of the user interface that lets you add a new site to the white list. There are other, more sophisticated ways to do this; you may also want to include some UI that lets you view the white list or edit it as a list. In this part of the tutorial, however, we only provide the means of adding an URL provided as a string (which is not checked for validity) and passing it through to the <code>AddSite</code> API we defined in the earlier part of the tutorial.</p>
+
+<pre>&lt;separator class="thin"/&gt;
+
+&lt;hbox align="center"&gt;
+ &lt;textbox id="url.input" flex="1"/&gt;
+ &lt;button label="Add this URL" oncommand="addThisSite();"/&gt;
+&lt;/hbox&gt;
+</pre>
+
+<p>This snippet introduces a couple of new general layout widgets in XUL. The separator that appears at the top of this snippet creates a little divider between widgets like the kind you see in menus that divide sets of functionality available there. The parent of the textbox that users enter an URL into is something called an <code>&lt;hbox/&gt;</code>, which is a layout widget - often invisible - that controls the way its child elements are rendered. In this case the <code>&lt;hbox/&gt;</code> centers the textbox and the button children, and it orients them horizontally (in contrast to the <code>&lt;vbox/&gt;</code>, which orients its children vertically).</p>
+
+<p>Notice also that when it's clicked, the button executes a JavaScript function called <code>addThisSite()</code>, which we've already defined in the <code>weblock.js</code> file in <a href="#Client_Code_Overview">Client Code Overview</a> above.</p>
+
+<h4 id="weblock.xul" name="weblock.xul"><code>weblock.xul</code></h4>
+
+<pre>&lt;?xml version="1.0"?&gt;
+&lt;?xml-stylesheet href="chrome://global/skin/" type="text/css"?&gt;
+
+&lt;dialog id="weblock_mgg"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="Web Lock Manager"
+ style="width: 30em;"
+ persist="screenX screenY"
+ screenX="24" screenY="24"&gt;
+
+ &lt;script src="chrome://weblock/content/weblock.js"/&gt;
+
+ &lt;hbox&gt;
+ &lt;separator orient="vertical" class="thin"/&gt;
+ &lt;vbox flex="1"&gt;
+ &lt;separator class="thin"/&gt;
+ &lt;hbox align="center"&gt;
+ &lt;textbox id="dialog.input" flex="1"/&gt;
+ &lt;button label="Add this URL"
+ oncommand="addThisSite();"/&gt;
+ &lt;/hbox&gt;
+ &lt;hbox align="center"&gt;
+ &lt;radiogroup onchange="toggleLock();"&gt;
+ &lt;radio label="lock"/&gt;
+ &lt;radio label="unlock"/&gt;
+ &lt;/radiogroup&gt;
+ &lt;spacer flex="1"/&gt;
+ &lt;/hbox&gt;
+ &lt;/vbox&gt;
+ &lt;/hbox&gt;
+
+&lt;/dialog&gt;
+</pre>
+
+<h3 id="Overlaying_New_User_Interface_Into_Mozilla" name="Overlaying_New_User_Interface_Into_Mozilla">Overlaying New User Interface Into Mozilla</h3>
+
+<p>你已经有了一个可以跟<strong>WebLock</strong>组件交互的对话框, 但是你怎么把它装到browser中? 然后你怎么访问它呢? 当安装和准备好以后,<strong>WebLock</strong> 组件已经可以用了: XPCOM finds it and adds it to the list of registered components, and then WebLock observes the XPCOM startup event and initializes itself.</p>
+
+<p>But you still have to add your new UI into the browser so it can call the component, and the Mozilla overlay mechanism is the way to do this. Overlays 是 XUL文件可以用来注册他们自己以便动态地嵌入到Browser UI合适的位置.</p>
+
+<h4 id="webLockOverlay.xul" name="webLockOverlay.xul"><code>webLockOverlay.xul</code></h4>
+
+<p>The XUL that defines the new icon is small: 这是一个调用JavaScript function来装载前面我们定义的<code>weblock.xul</code> 文件的小图表. The icon is actually a separate <code>&lt;statusbarpanel/&gt;</code> element that gets overlaid into the main browser, along with some JavaScript and some CSS to control the behavior and appearance of the element, respectively. Here is that XUL file in its entirety:</p>
+
+<p><span id="The_WebLock_Overlay"><a id="The_WebLock_Overlay"></a><strong>The WebLock Overlay</strong></span></p>
+
+<pre>&lt;?xml version="1.0"?&gt;
+&lt;?xml-stylesheet href="chrome://navigator/content/weblock.css" type="text/css"?&gt;
+
+&lt;overlay id="weblockOverlay"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"&gt;
+
+ &lt;script type="application/x-javascript"
+ src="chrome://weblock/content/weblock.js"/&gt;
+
+ &lt;statusbar id="status-bar"&gt;
+ &lt;statusbarpanel class="statusbarpanel-iconic"
+ id="weblock-status"
+ insertbefore="offline-status"
+ oncommand="loadWebLock();"
+ status="none"/&gt;
+ &lt;/statusbar&gt;
+
+&lt;/overlay&gt;
+</pre>
+
+<p>文件的根元素不是<code>&lt;window/&gt;</code> 而是<code>&lt;overlay/&gt;</code>. In overlays 被 XUL elements用来把他们和其他元素相区分的<code>id</code>属性被设置称为browser中他们要嵌入部分的值. In this case, the weblock <code>&lt;statusbarpanel/&gt;</code> appears as a child of the <code>&lt;statusbar/&gt;</code> element with <code>id</code> "status-bar". This <code>id</code> is the same one used by the <code>&lt;statusbar/&gt;</code> in <code>navigator.xul</code>, which means that the overlay mechanism will merge the new UI here (i.e., the weblock statusbarpanel) and the UI already defined within that browser <code>&lt;statusbar/&gt;</code> at runtime.</p>
+
+<h3 id="Other_Resources" name="Other_Resources">Other Resources</h3>
+
+<p>这部分描述剩下的需要添加和打包到<strong>WebLock</strong>组件来提供web locking用户界面的文件。</p>
+
+<div class="side-note">
+<p><span id="Other_Front_End_Resources"><a id="Other_Front_End_Resources"></a><strong>Other Front End Resources</strong></span></p>
+
+<p>在某些UI包中, 本地化 resources are also defined. These include DTDs in which the language in which the UI is labelled can be extracted into external files, which are swapped with DTDs for other languages. For example, user interface packages often include an English DTD that defines labels and strings for button and menus and other elements in the interface. When the user selects a different<em>language pack</em> , all of the English that's been externalized in these files is dynamically replaced with the new choice. In addition to DTDs, the localization parts of a user interface may also include string bundles in which strings that are used in the interface JavaScript can be similarly replaced. 有一些技术通过单独的文件来提供这种功能. 包含<em>bindings</em> in XML files,<em>metadata</em> in RDF files, whole collections of CSS files called<em>skins</em> , and others.</p>
+</div>
+
+<h4 id="weblock.css" name="weblock.css">weblock.css</h4>
+
+<p>The following style rules are defined in <code>weblock.css</code>, a CSS file that is loaded by the overlay and applied to the icon in the browser that reflects the current status of the web lock and provides access to the web lock manager dialog.</p>
+
+<pre>statusbarpanel#weblock-status
+{
+ list-style-image: url("chrome://weblock/wlock.gif");
+}
+
+statusbarpanel#weblock-status[status="locked"]
+{
+ list-style-image: url("chrome://weblock/wl-lock.gif");
+}
+
+statusbarpanel#weblock-status[status="unlocked"]
+{
+ list-style-image: url("chrome://weblock/wl-un.gif");
+}
+</pre>
+
+<p>The style rules are distinguished by the state of the <code>status</code> attribute on the element in the XUL with the <code>id</code> "weblock-status." As you can see above, when the status of the element is set to "locked", the image <code>wl-lock.gif</code> is used to show the state, and when the web locking is unlocked, it uses <code>wl-un.gif</code>. (Note: We include three images to represent the state of the weblock, but <code>wlock.gif</code> and <code>wl-lock.gif</code> are identical, since weblock is presumed to be unlocked when it's loaded. This tutorial makes use of only two different states, but you can further customize the look of the weblock using the three images if you wish.)</p>
+
+<p>Since the presentation of the weblock manager dialog itself doesn't require any special styles, these are all the rules you need in the <code>weblock.css</code>. Note that the <code>weblock.xul</code> file in which the manager is defined imports only the global skin:</p>
+
+<pre>&lt;?xml-stylesheet href="chrome://global/skin/" type="text/css"?&gt;
+</pre>
+
+<p>Save <code>weblock.css</code> in your working directory.</p>
+
+<p>You should now have the four files listed at the top of this chapter as the "packing list" for the <strong>WebLock</strong> package (see <a href="#User_Interface_Package_List">User Interface Package List</a>). Don't worry for now about where these files are. 下一章, <a href="cn/Creating_XPCOM_Components/Packaging_WebLock">Packaging WebLock</a>, 我们讨论如何打包这些文件以便 <strong>WebLock</strong> 组件或者别的资源利用它们.</p>
+
+<h4 id="Image_Resources" name="Image_Resources">Image Resources</h4>
+
+<p>如果你学习本教程并且希望使用<strong>WebLock</strong>组件在statusbar中的图片,你可以从 <a class="external" href="http://www.brownhen.com/weblock下载他们和其他" rel="freelink">http://www.brownhen.com/weblock下载他们和其他</a><strong>weblock</strong>相关资源. The GIF files that represent the various states are:</p>
+
+<ul>
+ <li><code>wlock.gif</code></li>
+ <li><code>wl-lock.gif</code></li>
+ <li><code>wl-un.gif</code></li>
+</ul>
+
+<ol>
+ <li><div class="blockIndicator note"><strong>Note:</strong> other-mozlike-browsers</div> 或者你可能会很喜欢这些东西. 还有一些基于 Gecko的browsers ,例如Beonex 和 IBM Web Browser 也会共享很多Mozilla用户界面成分, 你也可能装载 <strong>WebLock</strong> 组件和用户界面到其中. 不过请注意, <strong>WebLock</strong>有可能还不能保证完全安装到Mozilla Firefox,因为firefox有一些新的变化 (这本书是2003的版本).</li>
+</ol>
+
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/Creating_XPCOM_Components:Finishing_the_Component" style="float: left;">« 上一页</a><a href="/zh-CN/docs/Creating_XPCOM_Components:Packaging_WebLock">下一页 »</a></p>
+</div> <p></p><div class="licenseblock">
+<p>Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the <a class="external" href="http://www.opencontent.org/openpub/" rel="noopener">Open Publication License</a>, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.</p>
+</div><p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/component_internals/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/component_internals/index.html
new file mode 100644
index 0000000000..d29da9a71d
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/component_internals/index.html
@@ -0,0 +1,217 @@
+---
+title: Component Internals
+slug: Mozilla/Tech/XPCOM/Guide/Creating_components/Component_Internals
+translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/Component_Internals
+---
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/创建_XPCOM组件/使用XPCOM组件" style="float: left;">« 上一页</a><a href="/zh-CN/docs/Creating_XPCOM_Components/Creating_the_Component_Code">下一页 »</a></p>
+</div> 前几章以组件使用者的角度介绍了XPCOM 组件, 本章将以软件开发者的角度讨论XPCOM.您可以继续阅读以明白XPCOM的一般实现方式, 或者您也可以跳到下一章, 在下一章,以WebLock为例向一步一步您介绍 组件的开发过程。 <span class="comment">XXX mediawiki...</span><span class="comment">XXX sucks</span><p></p>
+
+<h3 id="Creating_Components_in_C.2B.2B" name="Creating_Components_in_C.2B.2B">使用C++创建组件</h3>
+
+<p>让我们开始研究怎样用c++创建XPCOM组件. 最常见的组件是以C++编写并编译成共享库(如Windows平台的DLL或者Unix平台的DSO)。</p>
+
+<p>The illustration below shows the basic relationship between the shared library containing the component implementation code you write and the XPCOM framework itself. In this diagram, the outer boundary is that of the module, the shared library in which a component is defined.</p>
+
+<p><span id="A_Component_in_the_XPCOM_Framework"><a id="A_Component_in_the_XPCOM_Framework"></a><strong>A Component in the XPCOM Framework</strong></span></p>
+
+<p><img alt="Image:component-internals-framework.png" class="internal" src="/@api/deki/files/615/=Component-internals-framework.png"></p>
+
+<p>When you build a component or module and compile it into a library, it must export a single method named <code>NSGetModule</code>. This <code>NSGetModule</code> function is the entry point for accessing the library. It gets called during registration and unregistration of the component, and when XPCOM wants to discover what interfaces or classes the module/library implements. In this chapter we will outline this entire process.</p>
+
+<p>As <a href="#A_Component_in_the_XPCOM_Framework">A Component in the XPCOM Framework</a> illustrates, in addition to the <code>NSGetModule</code> entry point, there are <code>nsIModule</code> and <code>nsIFactory</code> interfaces that control the actual creation of the component, and also the string and XPCOM glue parts, which we'll discuss in some detail in the next section (see <a href="/en/Creating_XPCOM_Components/Component_Internals#XPCOM_Glue" title="en/Creating_XPCOM_Components/Component_Internals#XPCOM_Glue">XPCOM Glue</a>). These latter supply ease-of-development utilities like smart pointers, generic modules support, and simple string implementations. The largest and possibly most complex part of a component is the code specific to the component itself.</p>
+
+<div class="side-note">
+<p><span id="But_Where_Are_the_Components?"><a id="But_Where_Are_the_Components?"></a><strong>But Where Are the Components?</strong></span></p>
+
+<p>Components reside in modules, and those modules are defined in shared library files that typically sit in the <em>components</em> directory of an XPCOM application.</p>
+
+<p>A set of default libraries stored in this components directory makes up a typical Gecko installation, providing functionality that consists of networking, layout, composition, a cross-platform user interface, and others.</p>
+
+<p>Another, even more basic view of this relationship of components to the files and interfaces that define them is shown in <a href="/en/Creating_XPCOM_Components/Creating_the_Component_Code" title="en/Creating_XPCOM_Components/Creating_the_Component_Code">Onion Peel View of XPCOM Component Creation</a> in the next chapter. The component is an abstraction sitting between the actual module in which it is implemented and the objects that its factory code creates for use by clients.</p>
+</div>
+
+<h3 id="XPCOM_Initialization" name="XPCOM_Initialization">XPCOM Initialization</h3>
+
+<p>To understand why and when your component library gets called, it is important to understand the XPCOM initalization process. When an application starts up, that application may <em>initialize</em> XPCOM. The sequence of events that kicks off this XPCOM initialization may be triggered by user action or by the application startup itself. A web browser that embeds Gecko, for example, may initialize XPCOM at startup through the embedding APIs. Another application may delay this startup until XPCOM is needed for the first time. In either case, the initialization sequence within XPCOM is the same.</p>
+
+<p>XPCOM starts when the application makes a call to initialize it. Parameters passed to this startup call allow you to configure some aspects of XPCOM, including the customization of location of specific directories. The main purpose of the API at this point is to change which <em>components</em> directory XPCOM searches when it looks for XPCOM components. This is how the API is used, for example, in the <em>Gecko Runtime Environment</em> (GRE).</p>
+
+<div class="side-note">
+<p><span id="XPCOM_Startup"><a id="XPCOM_Startup"></a><strong>XPCOM Startup</strong></span></p>
+
+<p>The six basic steps to XPCOM startup are as follows:</p>
+
+<ol>
+ <li>Application starts XPCOM.</li>
+ <li>XPCOM sends a notification that it's beginning startup.</li>
+ <li>XPCOM finds and processes the <em>component manifest</em> (see <a href="#Component_Manifests">Component Manifests</a> below).</li>
+ <li>XPCOM finds and processes the <em>type library manifest</em> (see <a href="#Type_Library_Manifests">Type Library Manifests</a> below).</li>
+ <li>If there are new components, XPCOM registers them:
+ <ol>
+ <li>XPCOM calls autoregistration start.</li>
+ <li>XPCOM registers new components.</li>
+ <li>XPCOM calls autoregistration end.</li>
+ </ol>
+ </li>
+ <li>Complete XPCOM startup: XPCOM notifies that it's begun.</li>
+</ol>
+
+<p>Component manifests and type library manifests are described in the following section, <a href="#XPCOM_Registry_Manifests">XPCOM Registry Manifests</a>.</p>
+</div>
+
+<h4 id="XPCOM_Registry_Manifests" name="XPCOM_Registry_Manifests">XPCOM Registry Manifests</h4>
+
+<p>XPCOM uses special files called manifests to track and persist information about the components to the local system. There are two types of manifests that XPCOM uses to track components:</p>
+
+<h5 id="Component_Manifests" name="Component_Manifests">Component Manifests</h5>
+
+<p>When XPCOM first starts up, it looks for the <em>component manifest</em>, which is a file that lists all registered components, and stores details on exactly what each component can do. XPCOM uses the component manifest to determine which components have been overridden. Starting with Mozilla 1.2, this file is named <code>compreg.dat</code> and exists in the <em>components</em> directory, but there are efforts to move it out of this location to a less application-centric (and thus more user-centric) location. Any Gecko-based application may choose to locate it elsewhere. XPCOM reads this file into an in-memory database.</p>
+
+<div class="side-note">
+<p><span id="Component_Manifests"><a id="Component_Manifests"></a><strong>Component Manifests</strong></span></p>
+
+<p>The component manifest is a mapping of files to components and components to classes. It specifies the following information:</p>
+
+<ul>
+ <li>Location on disk of registered components with file size</li>
+ <li>Class ID to Location Mapping</li>
+ <li>Contract ID to Class ID Mapping</li>
+</ul>
+
+<p>The component manifest maps component files to unique identifiers for the specific implementations (class IDs), which in turn are mapped to more general component identifiers (contract IDs).</p>
+</div>
+
+<h5 id="Type_Library_Manifests" name="Type_Library_Manifests">Type Library Manifests</h5>
+
+<p>Another important file that XPCOM reads in is the <em>type library manifest</em> file. This file is also located in the <em>components</em> directory and is named <code>xpti.dat</code>. It includes the location and search paths of all type library files on the system. This file also lists all known interfaces and links to the type library files that define these interface structures. These type library files are at the core of XPCOM scriptablity and the binary component architecture of XPCOM.</p>
+
+<div class="side-note">
+<p><span id="Type_Library_Manifests"><a id="Type_Library_Manifests"></a><strong>Type Library Manifests</strong></span></p>
+
+<p>Type library manifests contain the following information:</p>
+
+<ul>
+ <li>location of all type library files</li>
+ <li>mapping of all known interfaces to type libraries where these structures are defined</li>
+</ul>
+</div>
+
+<p>Using the data in these two manifests, XPCOM knows exactly which component libraries have been installed and what implementations go with which interfaces. Additionally, it relates the components to the type libraries in which the binary representations of the interfaces they support are defined.</p>
+
+<p>The next section describes how to hook into the XPCOM startup and registration process and make the data about your component available in these manifests, so that your component will be found and registered at startup.</p>
+
+<h4 id="Registration_Methods_in_XPCOM" name="Registration_Methods_in_XPCOM">Registration Methods in XPCOM</h4>
+
+<div class="side-note">
+<p><span id="What_Is_XPCOM_Registration?"><a id="What_Is_XPCOM_Registration?"></a><strong>What Is XPCOM Registration?</strong></span></p>
+
+<p>In a nutshell, registration is the process that makes XPCOM aware of your component(s). As this section and the next describe, you can register your component explicitly during installation, or with the <code>regxpcom</code> program, or you can use the autoregistration methods in the Service Manager to find and register components in a specified components directory:</p>
+
+<ul>
+ <li>XPInstall APIs</li>
+ <li><code>regxpcom</code> command-line tool</li>
+ <li><code>nsIComponentRegistrar</code> APIs from Service Manager</li>
+</ul>
+
+<p>The registration process is fairly involved. This section introduces it in terms of XPCOM initialization, and the next chapter describes what you have to do in your component code to register your component with XPCOM.</p>
+</div>
+
+<p>Once the manifest files are read in, XPCOM checks to see if there are any components that need to be registered. There are two supported ways to go about registering your XPCOM component. The first is to use <em>XPInstall</em>, which is an installation technology that may or may not come with a Gecko application and provides interfaces for registering your component during installation. Another, more explicit way to register your component is to run the application <code>regxpcom</code>, which is built as part of Mozilla and is also available in the Gecko SDK. <code>regxpcom</code> registers your component in the default component registry.</p>
+
+<p>A Gecko embedding application may also provide its own way of registering XPCOM components using the interface that is in fact used by both XPInstall and <code>regxpcom</code>, <code>nsIComponentRegistrar</code>. An application, for example, could provide a "registration-less" component directory whose components are automatically registered at startup and unregistered at shutdown. Component discovery does not currently happen automatically in non-debug builds of Gecko, however.</p>
+
+<p>When the registration process begins, XPCOM broadcasts to all registered observers a notification that says XPCOM has begun the registration of new components. After all components are registered, another notification is fired saying that XPCOM is done with the registration step. The <code>nsIObserver</code> interface that handles this notification is discussed in <a href="/en/Creating_XPCOM_Components/Starting_WebLock" title="en/Creating_XPCOM_Components/Starting_WebLock">Starting WebLock</a>.</p>
+
+<p>Once registration is complete and the notifications have fired, XPCOM is ready to be used by the application. If XPCOM registered your component, then it will be available to other parts of the XPCOM system. The <a href="#XPCOM_Initialization">XPCOM Initialization</a> section in this chapter describes registration in more detail.</p>
+
+<h4 id="Autoregistration" name="Autoregistration">Autoregistration</h4>
+
+<p>The term <em>autoregistration</em> is sometimes used synonymously with registration in XPCOM. In the <a href="#What_Is_XPCOM_Registration?">What Is XPCOM Registration?</a> note, we describe the three ways you can register components with XPCOM. Sometimes, applications use the <code>nsIComponentRegistrar</code> interface and create their own code for watching a particular directory and registering new components that are added there, which is what's often referred to as <em>autoregistration</em>. You should always know what the installation and registration requirements are for the applications that will be using your component.</p>
+
+<h4 id="The_Shutdown_Process" name="The_Shutdown_Process">The Shutdown Process</h4>
+
+<p>When the application is ready to shutdown XPCOM, it calls <code>NS_ShutdownXPCOM</code>. When that method is called, the following sequence of events occurs:</p>
+
+<ol>
+ <li>XPCOM fires a shutdown notification to all registered observers.</li>
+ <li>XPCOM closes down the Component Manager, the Service Manager and associated services.</li>
+ <li>XPCOM frees all global services.</li>
+ <li>NS_ShutdownXPCOM returns and the application may exit normally.</li>
+</ol>
+
+<div class="side-note">
+<p><span id="The_Unstoppable_Shutdown"><a id="The_Unstoppable_Shutdown"></a><strong>The Unstoppable Shutdown</strong></span></p>
+
+<p>Note that shutdown observation is unstoppable. In other words, the event you observe cannot be used to implement something like a "Are you sure you want to Quit?" dialog. Rather, the shutdown event gives the component or embedding application a last chance to clean up any leftovers before they are released. In order to support something like an "Are you sure you want to quit" dialog, the application needs to provide a higher-level event (e.g., <code>startShutdown()</code>) which allows for cancellation.</p>
+
+<p>Note also that XPCOM services may deny you access once you have received the shutdown notification. It is possible that XPCOM will return an error if you access the <code>nsIServiceManager</code> at that point, for example, so you may have to keep a reference-counted pointer to the service you are interested in using during this notification.</p>
+</div>
+
+<h4 id="Component_Loaders" name="Component_Loaders">Component Loaders</h4>
+
+<p>Components can be written in many languages. So far this book has been focusing on "native components," shared libraries exporting a <code>NSGetModule</code> symbol. But if there is a <em>component loader</em> for Javascript installed, then you can also write a JavaScript component.</p>
+
+<p>To register, unregister, load and manage various component types, XPCOM abstracts the interface between the XPCOM component and XPCOM with the Component Loader. This loader is responsible for initialization, loading, unloading, and supporting the <code>nsIModule</code> interface on behalf of each component. It is the Component Loader's responsibility to provide scriptable component support.</p>
+
+<p>When building a "native" component, the component loader looks for an exported symbol from the components shared library. "Native" here includes any language that can generate a platform native dynamically loaded library. Scripting languages and other "non-native" languages usually have no way to build native libraries. In order to have "non-native" XPCOM components work, XPCOM must have a special component loader which knows how to deal with these type of components.</p>
+
+<p>XPConnect, for example, provides a component loader that makes the various types, including the interfaces and their parameters, available to JavaScript. Each language supported by XPCOM must have a component loader.</p>
+
+<h4 id="Three_parts_of_a_XPCOM_Component_Library" name="Three_parts_of_a_XPCOM_Component_Library">Three parts of a XPCOM Component Library</h4>
+
+<p>XPCOM is like an onion<span class="comment">or a parfait! Everybody likes parfaits</span>. XPCOM components have at least three layers. From the innermost and moving outward these layers include:</p>
+
+<ul>
+ <li>The core XPCOM object</li>
+ <li>The factory code</li>
+ <li>The module code</li>
+</ul>
+
+<p>The core XPCOM object is the object that will implement the functionality you need. For example, this is the object that may start a network download and implement interfaces that will listen to the progress. Or the object may provide a new content type handler. Whatever it does, this object is at the core of the XPCOM component, and the other layers are supporting it, plugging it into the XPCOM system. A single library may have many of these core objects.</p>
+
+<p>One layer above the core object is the factory code. The factory object provides a basic abstraction of the core XPCOM object. <a href="/en/Creating_XPCOM_Components/An_Overview_of_XPCOM" title="en/Creating_XPCOM_Components/An_Overview_of_XPCOM">An Overview of XPCOM</a> discussed the factory design pattern that's used in a factory object. At this layer of the XPCOM Component Library, the factory objects are factories for the core XPCOM objects of the layer below.</p>
+
+<p>One more layer outward is the module code. The module interface provides yet another abstraction - this time of the factories - and allows for multiple factory objects. From the outside of the component library, there is only the single entry point, <code>NSGetModule()</code>. This point of entry may fan out to any number of factories, and from there, to any number of XPCOM objects.</p>
+
+<p>The factory design pattern in XPCOM is represented by the <code>nsIFactory</code> interface. The module layer is represented by the <code>nsIModule</code> interface. Most component libraries only need these two interfaces, along with the <code>nsISupports</code> interface, to have XPCOM load, recognize, and use their core object code.</p>
+
+<p>In the next section, we'll be writing the code that actually compiles into a component library, and you will see how each layer is implemented and how each interface is used. Following this initial, verbose demonstration of the APIs, we will introduce a faster more generic way of implementing the module and factory code using macros, which can make components much easier to create.</p>
+
+<h3 id="XPCOM_Glue" name="XPCOM_Glue">XPCOM Glue</h3>
+
+<p>XPCOM contains a lot of stuff. Most XPCOM interfaces are not frozen and are only meant to be used by the Gecko internals and not by clients. XPCOM provides many data structures from linked lists to <a class="external" href="http://en.wikipedia.org/wiki/AVL_tree">AVL trees</a>. It's tempting to reuse <code>nsVoidArray</code> or another publicly available class instead of writing your own linked list, but this may prove to be a fatal mistake. The class can change at any time and give you unexpected behavior.</p>
+
+<p>XPCOM makes for a very open environment. At runtime you can acquire any service or component by merely knowing a CID or Contract ID along with an IID. At last count there were over 1300 interfaces defined in XPIDL. Of those 1300 interfaces, less than 100 were frozen, which means that a developer is likely to stumble upon useful interfaces that aren't frozen. Unless an interface is explicitly marked "FROZEN" in the IDL comments, your component may possibly break or crash along with a version change.</p>
+
+<h4 id="The_Glue_Library" name="The_Glue_Library">The Glue Library</h4>
+
+<p>In general, you should avoid any interfaces, symbols in XPCOM, or other part of Gecko libraries that aren't frozen. However, there are some unfrozen tools in XPCOM that are used so often they are practically required parts of component programming.</p>
+
+<p>The smart pointer class, <code>nsCOMPtr</code>, for example, which makes reference counting less tedious and error-prone, is not actually frozen, and neither is <code>nsDebug</code>, a class for aiding in tracking down bugs, nor is <code>nsMemory</code>, a class to ensure that everyone uses the same heap, generic factory, and module. Instead of asking every developer to find and copy these various files into their own application, XPCOM provides a single library of "not-ready-to-freeze-but-really-helpful" classes that you can link into your application, as the following figure demonstrates.</p>
+
+<p><span id="XPCOM_Glue_and_Tools"><a id="XPCOM_Glue_and_Tools"></a><strong>XPCOM Glue and Tools</strong></span></p>
+
+<p><img alt="Image:xpcom-glue-tools.png" class="internal" src="/@api/deki/files/978/=Xpcom-glue-tools.png"></p>
+
+<p>This is the glue library. It provides a bridge, or "glue" layer, between your component and XPCOM.</p>
+
+<p>A version of the glue library is built into XPCOM, and when your component uses it, it links a snapshot of this library: it includes a copy of these unfrozen classes directly, which allows the XPCOM library version to change without affecting the software. There is a slight footprint penalty to linking directly, but this gives your component freedom to work in any recent environment. If footprint is a big issue in your component or application, you can trim out the pieces you don't need.</p>
+
+<h4 id="XPCOM_String_Classes" name="XPCOM_String_Classes">XPCOM String Classes</h4>
+
+<p>The base string types that XPCOM uses are <code>nsAString</code> and <code>nsACString</code>. These classes are described in the Mozilla String Guide (see <a href="/en/Creating_XPCOM_Components/Resources#Gecko_Resources" title="en/Creating_XPCOM_Components/Resources#Gecko_Resources">Gecko Resources</a>).</p>
+
+<p>The string classes that implement these abstract classes are another set of helpful, unfrozen classes in XPCOM. Most components and embedding applications need to link to some string class or other in order to utilize certain Gecko APIs, but the string code that Mozilla uses is highly complex and even more expensive than the glue code in terms of footprint (~100k). <code>nsEmbedString</code> and <code>nsEmbedCString</code> are available as very lightweight string implementations for component development, especially in small embedded applications. This string implementation does the bare minimum to support the <code>nsAString</code>/<code>nsACString</code> functionality.</p>
+
+<p>In your own component, you can go "slim" and restrict yourself to the <code>nsEmbedString</code> or go "hog wild" and use any of the the other strings. WebLock restricts itself to using the simple <code>nsEmbedString</code> family of classes.</p>
+
+<p><span id="String_Classes_and_XPCOM"><a id="String_Classes_and_XPCOM"></a><strong>String Classes and XPCOM</strong></span></p>
+
+<p><img alt="Image:strings-in-xpcom.png" class="internal" src="/@api/deki/files/867/=Strings-in-xpcom.png"></p>
+
+<p>The glue library provides stub functions for the public functions that XPCOM provides (see <code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/build/nsXPCOM.h" rel="custom">xpcom/build/nsXPCOM.h</a></code>). When the glue library is initialized, it dynamically loads these symbols from the XPCOM library, which allows the component to avoid linking directly with the XPCOM library. You shouldn't have to link to the XPCOM library to create a XPCOM component - in fact, if your component has to, then something is wrong. </p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/Creating_XPCOM_Components/Using_XPCOM_Components" style="float: left;">« 上一页</a><a href="/zh-CN/docs/Creating_XPCOM_Components/Creating_the_Component_Code">下一页 »</a></p>
+</div><p></p><div class="licenseblock">
+<p>Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the <a class="external" href="http://www.opencontent.org/openpub/" rel="noopener">Open Publication License</a>, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.</p>
+</div><p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/creating_the_component_code/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/creating_the_component_code/index.html
new file mode 100644
index 0000000000..a4aa535eca
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/creating_the_component_code/index.html
@@ -0,0 +1,727 @@
+---
+title: Creating the Component Code
+slug: Mozilla/Tech/XPCOM/Guide/Creating_components/Creating_the_Component_Code
+tags:
+ - XPCOM
+ - 所有分类
+translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/Creating_the_Component_Code
+---
+<p> </p>
+
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/Creating_XPCOM_Components:Component_Internals" style="float: left;">« 上一页</a><a href="/zh-CN/docs/Creating_XPCOM_Components:Using_XPCOM_Utilities_to_Make_Things_Easier">下一页 »</a></p>
+</div><p></p>
+
+<p>这一章叙述处理你的组件和XPCOM之间关联的基本代码。让组件被找到和注册是这个章节的目的。在后续章节中,我们开始建立<strong>WebLock</strong>组件本身的功能。</p>
+
+<p>注:有些部分采用英汉对照的方式。避免翻译的不准确!</p>
+
+<div class="side-note">
+<p><span id="Use_the_Calculator_(After_Learning_Long_Division)"><a id="Use_the_Calculator_(After_Learning_Long_Division)"></a><strong>Use the Calculator (After Learning Long Division)</strong></span></p>
+
+<p>You have to write a fair amount of code to create a component library that gets loaded into XPCOM. 一个XPCOM组件起码要实现三个XPCOM要求的接口, 通常还有其他一些. 这一章包含了可能你不会需要的更多代码,不过<a href="/cn/Creating_XPCOM_Components/Using_XPCOM_Utilities_to_Make_Things_Easier" title="cn/Creating_XPCOM_Components/Using_XPCOM_Utilities_to_Make_Things_Easier">Using XPCOM Utilities to Make Things Easier</a>会教你一些更简单和优雅的使用通用宏建立XPCOM组件的方式, 本章主要讲述基本的内容。 As in grade school when you learned long division, better tools like calculators come <em>after</em> you figure out what's actually happening. In this case, the long-hand implementation gives us an opportunity to talk about various features of XPCOM.</p>
+</div>
+
+<h3 id="What_We.27ll_Be_Working_On" name="What_We.27ll_Be_Working_On">What We'll Be Working On</h3>
+
+<p>The component we'll be working on in this book controls a special mode in your browser that prevents users from leaving the current domain or a set of safe domains. Once enabled, this weblock mode is password protected and persists until it is turned off by the password holder. It can be used to make the browser into a safe viewer for children, or for targeted "kiosk browsing," where the content is restricted to a particular server. <a href="#Web_Lock_User_Interface">Web Lock User Interface</a> shows the icon that is used to activate the web lock mode (leftmost in the status bar) once you have installed the <strong>WebLock</strong> component and the extra user interface.</p>
+
+<h3 id="接下来的内容"> 接下来的内容</h3>
+
+<p>文章后续的内容,将向读者描述一个使浏览器处在受控模式(web lock mode)的组件,该组件采用密码保护的方式防止用户从当前域或者一组安全的域中离开。这个组件可以使用在为未成年人提供受限内容或者是在一些小型电子浏览器中防止页面跳出特定服务内容。在用户安装了WebLock组件和额外的用户接口后,在状态栏的最左边,如图<a href="#Web_Lock_User_Interface">Web Lock User Interface</a>,可以用图标来激活受控模式(web lock mode)</p>
+
+<p><span id="Web_Lock_User_Interface"><a id="Web_Lock_User_Interface"></a><strong>Web Lock User Interface</strong></span></p>
+
+<p><img alt="Image:web-lock-ui.png" class="internal" src="/@api/deki/files/2727/=Web-lock-ui.png"></p>
+
+<p>实际上组件<strong>WebLock</strong>做的大多数事情是准备组件本身,找到需要的XPCOM接口, 并且挂接到现有的Gecko Browser功能.</p>
+
+<h3 id="Component_Registration" name="Component_Registration">Component Registration 组件注册</h3>
+
+<p>All XPCOM components - whether they're stored in shared libraries (DLLs, DSOs or dylibs), JavaScript files, or some other file - need to be <em>registered</em> before they can be used. Registration is a process that happens in all XPCOM applications, whether they're embedded Gecko clients, Mozilla, Netscape 7, Compuserve, or any other software that uses XPCOM. Registration provides the information that applications need in order to use components properly.</p>
+
+<p>所有的XPCOM 组件- 无论是存储在shared libraries (<abbr title="Dynamic Link Library (Windows)">DLLs</abbr>, <abbr title="Dynamic Shared Object (Linux)">DSOs</abbr> 还是 <abbr title="Dynamically linked library (OS X)">dylibs</abbr>), JavaScript文件,或者其他文件 - 使用前需要被<em>注册. </em>使用XPCOM的Gecko clients, Mozilla, Netscape 7, Compuserve, 或者其他程序,都需要注册,才能获得合适的组件信息。</p>
+
+<p>The <strong>WebLock</strong> component must do a number of things to register itself. Specifically, the component library has to contain implementations for the component-related interfaces described in this chapter: <code>nsIModule</code> and <code>nsIFactory</code>, which are entry points for your implementation code.</p>
+
+<p>想要注册 WebLock 组件必须做许多事情. 特别是, 组件库需要包含本章介绍的组件定义的接口: <code>nsIModule</code> and <code>nsIFactory</code>, 这是你的代码入口.</p>
+
+<p>Once your component implements these interfaces, the rest of the registration process itself is simple. Applications typically use <code>regxpcom</code>, described in the next section.</p>
+
+<p>如果你的组件实现了这些接口,注册将变的很容易. 应用中通常使用<code>regxpcom</code>注册, 在下一节描述.</p>
+
+<h4 id="regxpcom_.E7.A8.8B.E5.BA.8F" name="regxpcom_.E7.A8.8B.E5.BA.8F"><code>regxpcom</code> 程序</h4>
+
+<p>一个明确的注册组件方法是运行<code>regxpcom</code>. 不带任何参数启动<code>regxpcom</code>时, 程序把组件注册在缺省的组件注册表. 我们建议你如果是运行应用, 你可以拷贝你的组件到对应程序安装目录下的<code>components</code>目录. 拷贝好以后,运行<code>regxpcom</code>将注册包含你的组件在内的所有那个目录中的组件.</p>
+
+<p><code>regxpcom</code>在1.4 或更高版本有一些新的参数. 参看 <code>regxpcom 加&lt;code&gt;-h</code> 选项。</p>
+
+<h4 id=".E5.8F.A6.E5.A4.96.E7.9A.84.E6.B3.A8.E5.86.8C.E6.96.B9.E6.B3.95" name=".E5.8F.A6.E5.A4.96.E7.9A.84.E6.B3.A8.E5.86.8C.E6.96.B9.E6.B3.95">另外的注册方法</h4>
+
+<p>Gecko embedding 应用可能提供其他注册组件的方法. XPInstall, 是一个跨平台的安装技术,Mozilla用来安装浏览器和其他组件,这是一个选择。参看<a href="/cn/Creating_XPCOM_Components/Packaging_WebLock" title="cn/Creating_XPCOM_Components/Packaging_WebLock">Packaging WebLock</a>. 你可以询问你想要扩展的应用的作者看是否有其他扩展方法.</p>
+
+<h3 id="WebLock_Module_.E6.BA.90.E4.BB.A3.E7.A0.81.E6.A6.82.E8.A7.88" name="WebLock_Module_.E6.BA.90.E4.BB.A3.E7.A0.81.E6.A6.82.E8.A7.88">WebLock Module 源代码概览</h3>
+
+<p>As we mentioned in the previous section, components have layers. There are three main parts to every XPCOM component. From the innermost and moving outward, the first object is the XPCOM object. This is the object that contains the business logic, that implements functionality such as starting a network download, implementing interfaces that listen to the download progress, or providing a new content type handler. In <strong>Weblock</strong>, this is the part that brings together various Gecko services and prevents users from leaving the list of acceptable domains. In a way, the factory and module layers are glue to plug the XPCOM object into the larger XPCOM system.</p>
+
+<p>在前面的章节我们提到,组件是分层的.每一个XPCOM组件都有三部分.从内到外, 第一个对象是XPCOM对象. 这个对象包含了交互逻辑, 负责载入network, 执行一个监听载入过程或新content type的接口。. 在<strong>Weblock</strong>中, 这部分综合了各种Gecko服务并且防止用户离开允许的一些domain. In a way, the factory and module layers are glue to plug the XPCOM object into the larger XPCOM system.</p>
+
+<p>One layer above the object itself is the <code>nsIFactory</code> object. This object provides basic abstraction of the XPCOM object itself. As you can see in <span class="lang lang-en"><a href="/en/Creating_XPCOM_Components/Creating_the_Component_Code#Onion_Peel_View_of_XPCOM_Component_Creation" title="en/Creating_XPCOM_Components/Creating_the_Component_Code#Onion_Peel_View_of_XPCOM_Component_Creation"><font color="#638fa2">Onion Peel View of XPCOM Component Creation</font></a> </span>, the main accessor for the XPCOM object is <code>CreateInstance</code>, which is expected to return the object that matches a given CID and IID pair.</p>
+
+<p>XPCOM的上层是 <code>nsIFactory</code> 对象. nsIFactory是对XPCOM的基本抽象. 如同你在 <a href="#Onion_Peel_View_of_XPCOM_Component_Creation">Onion Peel View of XPCOM Component Creation</a>中看到的, 通过CreateInstance与XPCOM对象进行交互, 返回一个匹配给定的CID 和IID 的两个对象.</p>
+
+<p>Moving another layer outward is the <code>nsIModule</code>. This interface provides yet another abstraction of the <code>nsIFactory</code> object, and may allow for multiple <code>nsIFactory</code> objects. The key to this interface is that the return type of <code>getClassObject</code> does not have to be an <code>nsIFactory</code>. Instead, the <code>nsIModule</code> can ask for implementation details about the XPCOM object. This is very useful if the caller is required to know information about the component like its threading module, whether or not it's a singleton, its implementation language, and so forth. The interface used in this case is <code>nsIClassInfo</code>. Starting from the outside in, <span class="lang lang-en"><a href="/en/Creating_XPCOM_Components/Creating_the_Component_Code#Onion_Peel_View_of_XPCOM_Component_Creation" title="en/Creating_XPCOM_Components/Creating_the_Component_Code#Onion_Peel_View_of_XPCOM_Component_Creation"><font color="#638fa2">Onion Peel View of XPCOM Component Creation</font></a> </span>represents the sequence for constructing an XPCOM object.</p>
+
+<p>最外层是<code>nsIModule对象</code>. 他提供了对<code>nsIFactory</code> 的进一步抽象, 而且可能允许多个<code>nsIFactory</code>对象. 关键点是这个接口的方法<code>getClassObject</code>返回的不一定非要是<code>nsIFactory</code>. <code>nsIModule</code> 也可以用来询问 XPCOM 对象的细节. This is very useful if the caller is required to know information about the component like its threading module, whether or not it's a singleton, its implementation language, and so forth. 这是可以使用接口<code>nsIClassInfo</code>. 从外到内, <a href="#Onion_Peel_View_of_XPCOM_Component_Creation">Onion Peel View of XPCOM Component Creation</a> 表示了建立XPCOM对象的顺序.</p>
+
+<p><span id="Onion_Peel_View_of_XPCOM_Component_Creation"><a id="Onion_Peel_View_of_XPCOM_Component_Creation"></a><strong>Onion Peel View of XPCOM Component Creation</strong></span></p>
+
+<p><img alt="Image:xpcom-is-an-onion.png" class="internal" src="/@api/deki/files/2732/=Xpcom-is-an-onion.png"></p>
+
+<p>Before we begin looking at the various parts of the component and how they'll be implemented in the source, let's look at the module in <code>weblock.cpp</code> as a whole to see where we're going. The source we're referring to is listed in its entirety at the end of this chapter (see <a href="/cn/Creating_XPCOM_Components/Creating_the_Component_Code#webLock1.cpp" title="cn/Creating_XPCOM_Components/Creating_the_Component_Code#webLock1.cpp">webLock1.cpp</a>).</p>
+
+<p><strong>WebLock</strong> 组件的源代码包含三个类. 为了让<strong>WebLock</strong>组件工作在 Mozilla中, 你要为<strong>WebLock</strong>组件建立一个接口, <code>iWebLock</code>, where the actual work specific to the the web locking features happens. 建立 <code>WebLockModule</code> 实现<code>nsIModule</code>接口, 你也要建立 <code>WebLockFactory</code>实现 <code>nsIFactory</code>来建立一个为你的客户处理组件实例的工厂. These three interface implementations - of the component functionality, of the <code>nsIModule</code> interface, and of the <code>nsIFactory</code> interface that creates and manages instances for clients - are the basic sets of code you need to write to create an XPCOM component.</p>
+
+<div class="side-note">
+<p><span id="Basic_Structure_of_the_WebLock_Component_Source"><a id="Basic_Structure_of_the_WebLock_Component_Source"></a><strong>Basic Structure of the WebLock Component Source</strong></span></p>
+
+<p>The <code>weblock1.cpp</code> source file that defines these classes and the code you need to create a basic component has the following structure:</p>
+
+<pre class="eval"> * required includes and constants
+ * <strong>WebLock</strong>: public <code>iWebLock</code>
+ * <strong>WebLockFactory</strong>: public <code>nsIFactory</code>
+ * <strong>WebLockModule</strong>: public <code>nsIModule</code>
+</pre>
+
+<p>在XPCOM中, 所有这些类要实现 <code>nsISupports</code>.</p>
+</div>
+
+<h3 id=".E6.9B.B4.E8.BF.9B.E4.B8.80.E6.AD.A5:_.E9.9C.80.E8.A6.81.E7.9A.84_Includes_and_Constants" name=".E6.9B.B4.E8.BF.9B.E4.B8.80.E6.AD.A5:_.E9.9C.80.E8.A6.81.E7.9A.84_Includes_and_Constants">更进一步: 需要的 Includes and Constants</h3>
+
+<p>Let's take a look at the first several lines of code in the component and discuss what they mean in XPCOM. The includes and definitions at the top of an XPCOM source file can give you an idea about some of the data types and techniques we'll be discussing more in the upcoming chapters.</p>
+
+<p>介绍一下XPCOM的component代码里面前几行的意思。</p>
+
+<p>例如,<code>MOZILLA_STRICT_API</code>是一个变量,它用来遮蔽某些私有的、非XPCOM的头文件。 For example, <code>MOZILLA_STRICT_API</code> is a variable that shields you from certain private, non-XPCOM headers. For example, including <a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/components/nsIComponentManager.idl" rel="custom">nsIComponentManager.idl</a> without <code>MOZILLA_STRICT_API</code> defined will include the following headers, which are not supported across versions (unfrozen):</p>
+
+<ul>
+ <li><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/glue/nsComponentManagerUtils.h" rel="custom">nsComponentManagerUtils.h</a></li>
+ <li><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/components/nsComponentManagerObsolete.h" rel="custom">nsComponentManagerObsolete.h</a></li>
+</ul>
+
+<p>These variables are picked up by files that do not specify themselves as <code>MOZILLA_STRICT_API</code>.</p>
+
+<p><span id="Includes_and_Constants_in_%3Ccode%3Eweblock1.cpp%3C/code%3E"><a id="Includes_and_Constants_in_%3Ccode%3Eweblock1.cpp%3C/code%3E"></a><strong>Includes and Constants in <code>weblock1.cpp</code></strong></span></p>
+
+<pre>#include &lt;stdio.h&gt;
+
+// may be defined at the project level
+// in the makefile
+#define MOZILLA_STRICT_API
+
+#include "nsIModule.h"
+#include "nsIFactory.h"
+
+#include "nsIComponentManager.h"
+#include "nsIComponentRegistrar.h"
+
+// use classes to handle IIDs
+// classes provide methods for comparison: Equals, etc.
+static const nsIID kIModuleIID = NS_IMODULE_IID;
+static const nsIID kIFactoryIID = NS_IFACTORY_IID;
+static const nsIID kISupportsIID = NS_ISUPPORTS_IID;
+static const nsIID kIComponentRegistrarIID = NS_ICOMPONENTREGISTRAR_IID;
+
+
+// generate unique ID here with uuidgen
+#define SAMPLE_CID \
+{ 0x777f7150, 0x4a2b, 0x4301, \
+{ 0xad, 0x10, 0x5e, 0xab, 0x25, 0xb3, 0x22, 0xaa}}
+
+static const nsCID kSampleCID = SAMPLE_CID;
+</pre>
+
+<p><code>nsIModule.h</code> and <code>nsIFactory.h</code> are required to build your module successfully. They define the module and factory interfaces, and they contain a couple of important macros as well (see the following chapter for information about using these macros). The two other includes, <code>nsIComponentManager.h</code> and <code>nsIComponentRegistrar.h</code>, provide functions such as <code>RegisterFactoryLocation</code> that are required to implement the module and factory classes in your code.</p>
+
+<h4 id=".E6.A0.87.E8.AF.86.E7.AC.A6_in_XPCOM" name=".E6.A0.87.E8.AF.86.E7.AC.A6_in_XPCOM">标识符 in XPCOM</h4>
+
+<p>一组 <code>nsIID</code> 变量实际上是一些处理XPCOM用来支持客户和组件之间关系的128-bit标识符. The variable <code>kIFactoryIID</code>, for example, provides methods like <code>Equals()</code> that can be used to facilitate comparisons in the code, as in the following example from the Mozilla source:</p>
+
+<p><span id="Using_Class_Methods_to_Handle_Identifiers"><a id="Using_Class_Methods_to_Handle_Identifiers"></a><strong>Using Class Methods to Handle Identifiers</strong></span></p>
+
+<pre>if (aIID.Equals(NS_GET_IID(nsISupports)))
+{
+ *aInstancePtr = (void*)(nsISupports*)this;
+ NS_ADDREF_THIS();
+ return NS_OK;
+}
+</pre>
+
+<p>最后, <code>SAMPLE_CID</code> 是一个唯一标示组件的 CID . 所有的XPCOM中使用的128-bit数字 - 类和接口 IDs - 都是 UUIDs的例子, or <em>universal unique identifiers</em>, which were discussed in <a href="/cn/Creating_XPCOM_Components/What_is_XPCOM%3f#Object_Interface_Discovery" title="cn/Creating_XPCOM_Components/What_is_XPCOM?#Object_Interface_Discovery">Object Interface Discovery</a>.</p>
+
+<div class="side-note">
+<p>Generating CIDs</p>
+
+<p>为组件建立一个CID,你可以使用大多数Unix版本以及Miscrosoft Visual C++都包含的<code>uuidgen</code> 工具. <code>uuidgen</code> is a command-line tool that returns a unique 128-bit number when you call it with no arguments:</p>
+
+<pre>$ uuidgen
+ce32e3ff-36f8-425f-94be-d85b26e634ee
+</pre>
+
+<p>On Windows, a program called <code>guidgen.exe</code> does the same thing and also provides a graphical user interface if you'd rather point and click. Or you can use one of the special "bots" on IRC in <a class="link-irc" href="irc://irc.mozilla.org/mozilla">#developers</a>, where you can also get help from human beings.</p>
+
+<pre>irc irc.mozilla.org
+/join #developers
+/msg mozbot uuid
+</pre>
+
+<p>This command makes the bot generate and return a UUID, which you can then copy into your component source code.</p>
+</div>
+
+<p>Now that we've looked at the preliminaries, it's time to discuss the classes that this module provides and the way that they define the relationships of the component in XPCOM.</p>
+
+<h4 id="Coding_for_the_Registration_Process" name="Coding_for_the_Registration_Process">Coding for the Registration Process</h4>
+
+<p>当 XPCOM 第一次发现你的组件(via XPInstall or <code>regxpcom</code>, both of which are discussed in <a href="#Component_Installation_Overview">Component Installation Overview</a>), 第一件事是装载你的库并找到符号<code>NSGetModule</code>. 当这个专用的入口被调用, 它被传送XPCOM's Component Manager和组件存在的共享库位置.</p>
+
+<p>Component Manager是一个是XPCOM实现的用来包含建立对象和提供一些所有组件的综合信息的接口。磁盘的位置是通过另外一个接口 <code>nsIFile</code>传送的. This interface is XPCOM's abstraction of files and directories. An <code>nsIFile</code> object is usually a file or directory on a local volume, but it may represent something on a network volume as well.</p>
+
+<pre>nsresult NSGetModule(nsIComponentManager *servMgr,
+ nsIFile* location,
+ nsIModule** result);
+</pre>
+
+<p>XPCOM 需要成功调用 <code>NSGetModule</code>并返回接口<code>nsIModule</code>. 当你写一个 XPCOM 组件, 你实现了 <code>nsIModule</code> to do all of the necessary registration, unregistration, and object creation. <code>nsIModule</code> 有4个方法必须实现.<code>nsIModule</code> has four methods that must be implemented.</p>
+
+<h4 id="The_Registration_Methods" name="The_Registration_Methods">The Registration Methods</h4>
+
+<p>Two closely related registration methods are declared below.</p>
+
+<pre>NS_IMETHOD RegisterSelf(nsIComponentManager *aCompMgr,
+ nsIFile *aLocation,
+ const char *aLoaderStr,
+ const char *aType) = 0;
+
+NS_IMETHOD UnregisterSelf(nsIComponentManager *aCompMgr,
+ nsIFile *aLocation,
+ const char *aLoaderStr) = 0;
+</pre>
+
+<p><code>RegisterSelf</code> 在组件第一次被XPCOM注册的时候调用. 他只执行一次, which gives you a chance to add any one time setup functionality. The <code>RegisterSelf</code> 允许你的组件告诉XPCOM 你将支持什么功能. 注意所有你在 <code>RegisterSelf</code> 中做的都应该在 <code>UnregisterSelf</code>中撤销.</p>
+
+<p>首先, <code>NSGetModule</code>入口从你的库中被调用, 返回一个指向<code>nsIModule</code>的实现. 然后XPCOM调用<code>RegisterSelf</code>, passing parameters that we'll examine here.</p>
+
+<h5 id="The_RegisterSelf_Method" name="The_RegisterSelf_Method">The RegisterSelf Method</h5>
+
+<p>The first parameter is the <code>nsIComponentManager</code>, which provides a kind of entry point into managing the registration process. 你可以调用<code>QueryInterface</code> 来查找访问下面所述的其他组件管理接口.</p>
+
+<div class="side-note">
+<p><span id="The_Many_Faces_of_the_XPCOM_Component_Manager"><a id="The_Many_Faces_of_the_XPCOM_Component_Manager"></a><strong>The Many Faces of the XPCOM Component Manager</strong></span></p>
+
+<p>三个主要的组件管理接口, <code>nsIComponentManager</code>, <code>nsIServiceManager</code>, and <code>nsIComponentRegistrar</code>, are described below:</p>
+
+<ul>
+ <li><code>nsIComponentManager</code> - 建立组件并且返回组件实现细节。</li>
+ <li><code>nsIServiceManager</code> - 提供访问单根组件并且返回单根状态信息。</li>
+ <li><code>nsIComponentRegistrar</code> - 注册和注销工厂和组件;处理自动注册和发现已经注册的组件列表。</li>
+</ul>
+</div>
+
+<p>Your <code>RegisterSelf</code> method may call <code>QueryInterface</code> on the <code>nsIComponentManager</code> interface parameter to obtain the <code>nsIComponentRegistrar</code> or <code>nsIServiceManager</code>. <code>nsIServiceManager</code> can be used to obtain a singleton service, which can be useful if you have to register with a service other than the <code>nsIComponentRegistrar</code> if necessary. For example, you may want to get the service that is responsible for an event you want to be notified about. See <a href="/cn/Creating_XPCOM_Components/Starting_WebLock#Getting_Called_at_Startup" title="cn/Creating_XPCOM_Components/Starting_WebLock#Getting_Called_at_Startup">Getting Called at Startup</a> for an example of this.</p>
+
+<p>第二个参数<code>RegisterSelf</code>是正在注册组件的位置. This parameter is useful when the component needs to know where it has been installed or registered - as, for example, when other files must be stored or accessed relative to the component. This method is only called once, so you have to persist the location if you are going to use it later.</p>
+
+<p>The next two parameters are usually passed into the <code>nsIComponentRegistrar</code> methods and used by XPCOM to determine how to handle the component's registration. The <code>aLoaderStr</code> parameter, which is opaque and should not be modified, distinguishes components that are loaded from the same location specified by the <code>nsIFile</code> parameter. A single ZIP archive may store several XPCOM components, where every component in the archive has the same <code>nsIFile</code> parameter but the <code>aLoaderStr</code> parameter can be used to refer to the location within the ZIP archive.</p>
+
+<p>The last parameter specifies what kind of loader to use on the component. This is reserved as an optimization, for the most part, but it can be a useful way to extend XPCOM. Since XPCOM already knows internally what kind of file it has just loaded and called <code>RegisterSelf</code> on, passing this value to the registration methods is a shortcut for determining what kind of component is being registered.</p>
+
+<h5 id="nsIComponentRegistrar_Methods" name="nsIComponentRegistrar_Methods">nsIComponentRegistrar Methods</h5>
+
+<p>为了告诉XPCOM这个组件库实现了什么,调用方法:</p>
+
+<pre>NS_IMETHOD RegisterFactoryLocation(const nsCID &amp; aClass,
+ const char *aClassName,
+ const char *aContractID,
+ nsIFile *aFile,
+ const char *aLoaderStr,
+ const char *aType) = 0;
+</pre>
+
+<p>The last three parameters are the same as the three passed into the <code>RegisterSelf</code> method of <code>nsIModule</code> objects. All you have to do is forward these parameters from your <code>RegisterSelf</code> call into this method, leaving just the first three parameters.</p>
+
+<p>For any class that implements an XPCOM interface, the implementation must have a class identifier if it is to be shared with other parts of code via XPCOM. This identifier, called a CID, uniquely specifies the implementation. This CID can be created via the tool <code>uuidgen</code> on most operating systems, as in <a href="#The_Many_Faces_of_the_XPCOM_Component_Manager">The Many Faces of the XPCOM Component Manager</a> above. Given a CID and an IID, you can refer to any class in XPCOM. Consider the following:</p>
+
+<p><span id="Referencing_Objects_by_ID"><a id="Referencing_Objects_by_ID"></a><strong>Referencing Objects by ID</strong></span></p>
+
+<p><img alt="Image:referencing-objects-by-id.png" class="internal" src="/@api/deki/files/2676/=Referencing-objects-by-id.png"></p>
+
+<p>In this case, you have two implementations of the <code>nsISupports</code> interface. Each implementation has a separate CID. The interface also as an IID which is the same for both implementations. When specifying implementation A, the two required pieces of information are the CID of A and the IID of the interface that A supports. The code to register such an object is simple:</p>
+
+<pre>NS_IMETHODIMP
+SampleModule::RegisterSelf(nsIComponentManager *aCompMgr,
+ nsIFile* aPath,
+ const char* registryLocation,
+ const char* componentType)
+{
+ printf("Hello Mozilla Registration!\n\n");
+ nsIComponentRegistrar* compReg = nsnull;
+ nsresult rv =
+ aCompMgr-&gt;QueryInterface(kIComponentRegistrarIID,(void**)&amp; compReg);
+ if (NS_FAILED(rv))
+ return rv;
+ rv = compReg-&gt;RegisterFactoryLocation(kSampleCID,
+ "Sample Class",
+ nsnull,
+ aPath,
+ registryLocation,
+ componentType);
+ compReg-&gt;Release();
+ return rv;
+}
+</pre>
+
+<p>Unregistration follows the same logic. To unregister, all you have to do is pass the CID and the file which is passed into <code>UnregisterSelf</code>.</p>
+
+<h4 id=".E5.BB.BA.E7.AB.8B.E4.BD.A0.E7.9A.84.E7.BB.84.E4.BB.B6.E7.9A.84.E4.B8.80.E4.B8.AA.E5.AE.9E.E4.BE.8B" name=".E5.BB.BA.E7.AB.8B.E4.BD.A0.E7.9A.84.E7.BB.84.E4.BB.B6.E7.9A.84.E4.B8.80.E4.B8.AA.E5.AE.9E.E4.BE.8B">建立你的组件的一个实例</h4>
+
+<p>上面的例子用了 CID, 一旦注册以后,任何使用 XPCOM 的客户都可以访问你的组件,通过contract ID or CID. (Note that <code>RegisterSelf</code> method above does not register a contract ID - it simply passes null. This prevents clients from ever accessing the component with a contract ID.)</p>
+
+<p>为了让其他人访问, 你要公开组件包括它支持的接口的 CID 和/或者 contract ID. 上面的例子中,某人可能通过下面的方法建立一个 <strong>Sample</strong>对象 :</p>
+
+<pre>nsIComponentManager* compManager; // assume initialized
+
+nsISupports* sample;
+compManager-&gt;CreateInstance(kSampleCID,
+ nsnull,
+ kISupportsIID,
+ (void**)&amp;sample);
+</pre>
+
+<p>In the above snippet, we assume that the component manager has been initialized. In many cases this value is passed in or easily accessible. 如果还没有建立组件管理者,你总可以调用<code>NS_GetComponentManager()</code>来建立它. <a href="/cn/XPCOM_API_Reference" title="cn/XPCOM_API_Reference">XPCOM API Reference</a>中列出了一些全局的XPCOM方法.</p>
+
+<p>The first parameter of the call to <code>CreateInstance</code> specifies the component the client code is looking for, which is the same value passed to <code>RegisterFactoryLocation</code>. The next parameter is for aggregation, which the <strong>WebLock</strong> component does not support. The third parameter is the interface used to talk to the component. The last parameter is the out variable which will contain a valid object if and only if the method succeeds<sup><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Guide/Creating_components/Creating_the_Component_Code#endnote_non-null-out">[non-null-out]</a></sup>. The implementation of <code>CreateInstance</code> will ensure that the result will support the passed IID, <code>kISupportsIID</code>. The type of the variable <code>sample</code> should match the IID passed in as <code>kISupportsIID</code>.</p>
+
+<p>当 <code>CreateInstance</code> 被调用, XPCOM 查询所有的注册组件来匹配CID. XPCOM然后会装载对应的匹配 CID的组件,如果他还没有被装载的话. XPCOM 然后调用库的 <code>NSGetModule</code>. 最后它调用模块上的 <code>GetClassObject</code>. 这个方法是你来实现的,返回匹配 CID/IID 对的<code>nsIFactory</code>. To prepare your component code, you need to create a factory object for each object that you have registered with XPCOM.</p>
+
+<p>The main function that must be implemented in the <code>nsIFactory</code> interface is <code>CreateInstance</code>. The implementation follows a simple algorithm:</p>
+
+<ol>
+ <li>Create the raw object.</li>
+ <li>If that fails, return an out of memory error code.</li>
+ <li>Call <code>QueryInterface</code> on the new object.</li>
+ <li>If that fails, null the out param and free the new object.</li>
+ <li>Return the <code>nsresult</code> value from <code>QueryInterface</code>.</li>
+</ol>
+
+<p>Often, you don't have to create the object first because the factory implicitly knows what IIDs are supported. When this is not the case, however, doing it this way further abstracts the factories from their concrete classes. If you have a factory that knows every IID supported by the concrete base class, for example, then when you go to add a new supported interface you add this IID comparison in both the factory and the <code>QueryInterface</code> implementation in the concrete class.</p>
+
+<pre>NS_IMETHODIMP
+SampleFactory::CreateInstance(nsISupports *aOuter,
+ const nsIID &amp; iid,
+ void * *result)
+{
+ if (!result)
+ return NS_ERROR_INVALID_ARG;
+
+ Sample* sample = new Sample();
+ if (!sample)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ nsresult rv = sample-&gt;QueryInterface(iid, result);
+
+ if (NS_FAILED(rv)) {
+ *result = nsnull;
+ delete sample;
+ }
+
+ return rv;
+}
+</pre>
+
+<h3 id="webLock1.cpp" name="webLock1.cpp"><code>webLock1.cpp</code></h3>
+
+<p>Before any of the improvements and XPCOM tools we describe in the following chapter are brought in, the source code for the <strong>WebLock</strong> component that implements all the necessary interfaces looks like this.</p>
+
+<pre>#include &lt;stdio.h&gt;
+
+#define MOZILLA_STRICT_API
+
+#include "nsIModule.h"
+#include "nsIFactory.h"
+
+#include "nsIComponentManager.h"
+#include "nsIComponentRegistrar.h"
+
+static const nsIID kIModuleIID = NS_IMODULE_IID;
+static const nsIID kIFactoryIID = NS_IFACTORY_IID;
+static const nsIID kISupportsIID = NS_ISUPPORTS_IID;
+static const nsIID kIComponentRegistrarIID = NS_ICOMPONENTREGISTRAR_IID;
+
+
+#define SAMPLE_CID \
+{ 0x777f7150, 0x4a2b, 0x4301, \
+{ 0xad, 0x10, 0x5e, 0xab, 0x25, 0xb3, 0x22, 0xaa}}
+
+static const nsCID kSampleCID = SAMPLE_CID;
+
+class Sample: public nsISupports {
+ private:
+ nsrefcnt mRefCnt;
+ public:
+ Sample();
+ virtual ~Sample();
+
+ NS_IMETHOD QueryInterface(const nsIID &amp;aIID, void **aResult);
+ NS_IMETHOD_(nsrefcnt) AddRef(void);
+ NS_IMETHOD_(nsrefcnt) Release(void);
+
+};
+
+Sample::Sample()
+{
+ mRefCnt = 0;
+}
+
+Sample::~Sample()
+{
+}
+
+NS_IMETHODIMP
+Sample::QueryInterface(const nsIID &amp;aIID,
+ void **aResult)
+{
+ if (aResult == NULL) {
+ return NS_ERROR_NULL_POINTER;
+ }
+ *aResult = NULL;
+ if (aIID.Equals(kISupportsIID)) {
+ *aResult = (void *) this;
+ }
+ if (*aResult == NULL) {
+ return NS_ERROR_NO_INTERFACE;
+ }
+ AddRef();
+ return NS_OK;
+}
+
+NS_IMETHODIMP_(nsrefcnt) Sample::AddRef()
+{
+ return ++mRefCnt;
+}
+
+NS_IMETHODIMP_(nsrefcnt) Sample::Release()
+{
+ if (--mRefCnt == 0) {
+ delete this;
+ return 0;
+ }
+ return mRefCnt;
+}
+
+
+
+// factory implementation class for component
+class SampleFactory: public nsIFactory{
+ private:
+ nsrefcnt mRefCnt;
+ public:
+ SampleFactory();
+ virtual ~SampleFactory();
+
+ NS_IMETHOD QueryInterface(const nsIID &amp;aIID, void **aResult);
+ NS_IMETHOD_(nsrefcnt) AddRef(void);
+ NS_IMETHOD_(nsrefcnt) Release(void);
+
+ NS_IMETHOD CreateInstance(nsISupports *aOuter, const nsIID &amp; iid, void * *result);
+ NS_IMETHOD LockFactory(PRBool lock);
+
+};
+
+SampleFactory::SampleFactory()
+{
+ mRefCnt = 0;
+}
+SampleFactory::~SampleFactory()
+{
+}
+
+NS_IMETHODIMP
+SampleFactory::QueryInterface(const nsIID &amp;aIID,
+ void **aResult)
+{
+ if (aResult == NULL) {
+ return NS_ERROR_NULL_POINTER;
+ }
+ *aResult = NULL;
+ if (aIID.Equals(kISupportsIID)) {
+ *aResult = (void *) this;
+ }
+ else if (aIID.Equals(kIFactoryIID)) {
+ *aResult = (void *) this;
+ }
+
+ if (*aResult == NULL) {
+ return NS_ERROR_NO_INTERFACE;
+ }
+ AddRef();
+ return NS_OK;
+}
+
+NS_IMETHODIMP_(nsrefcnt) SampleFactory::AddRef()
+{
+ return ++mRefCnt;
+}
+
+NS_IMETHODIMP_(nsrefcnt) SampleFactory::Release()
+{
+ if (--mRefCnt == 0) {
+ delete this;
+ return 0;
+ }
+ return mRefCnt;
+}
+
+
+NS_IMETHODIMP
+SampleFactory::CreateInstance(nsISupports *aOuter,
+ const nsIID &amp; iid,
+ void * *result)
+{
+ if (!result)
+ return NS_ERROR_INVALID_ARG;
+
+ Sample* sample = new Sample();
+ if (!sample)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ nsresult rv = sample-&gt;QueryInterface(iid, result);
+
+ if (NS_FAILED(rv)) {
+ *result = nsnull;
+ delete sample;
+ }
+
+ return rv;
+}
+
+
+NS_IMETHODIMP
+SampleFactory::LockFactory(PRBool lock)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+
+
+
+
+
+// Module implementation
+class SampleModule : public nsIModule
+{
+ public:
+ SampleModule();
+ virtual ~SampleModule();
+
+ // nsISupports methods:
+ NS_IMETHOD QueryInterface(const nsIID &amp; uuid, void * *result);
+ NS_IMETHOD_(nsrefcnt) AddRef(void);
+ NS_IMETHOD_(nsrefcnt) Release(void);
+
+ // nsIModule methods:
+ NS_IMETHOD GetClassObject(nsIComponentManager *aCompMgr,
+ const nsCID &amp; aClass,
+ const nsIID &amp; aIID,
+ void * *aResult);
+ NS_IMETHOD RegisterSelf(nsIComponentManager *aCompMgr,
+ nsIFile *aLocation,
+ const char *aLoaderStr,
+ const char *aType);
+ NS_IMETHOD UnregisterSelf(nsIComponentManager *aCompMgr,
+ nsIFile *aLocation,
+ const char *aLoaderStr);
+ NS_IMETHOD CanUnload(nsIComponentManager *aCompMgr,
+ PRBool *_retval);
+
+ private:
+ nsrefcnt mRefCnt;
+};
+
+
+//----------------------------------------------------------------------
+
+SampleModule::SampleModule()
+{
+ mRefCnt = 0;
+}
+
+SampleModule::~SampleModule()
+{
+}
+
+
+// nsISupports implemention
+NS_IMETHODIMP_(nsrefcnt)
+SampleModule::AddRef(void)
+{
+ return ++mRefCnt;
+}
+
+
+NS_IMETHODIMP_(nsrefcnt)
+SampleModule::Release(void)
+{
+ if (--mRefCnt == 0) {
+ mRefCnt = 1; /* stabilize */
+ delete this;
+ return 0;
+ }
+ return mRefCnt;
+}
+
+NS_IMETHODIMP
+SampleModule::QueryInterface(REFNSIID aIID,
+ void** aInstancePtr)
+{
+ if (!aInstancePtr)
+ return NS_ERROR_NULL_POINTER;
+
+ nsISupports* foundInterface;
+
+ if (aIID.Equals(kIModuleIID)) {
+ foundInterface = (nsIModule*) this;
+ }
+ else if ( aIID.Equals(kISupportsIID) ) {
+ foundInterface = (nsISupports*) this;
+ }
+ else {
+ foundInterface = 0;
+ }
+
+ if (foundInterface) {
+ foundInterface-&gt;AddRef();
+ *aInstancePtr = foundInterface;
+ return NS_OK;
+ }
+
+ *aInstancePtr = foundInterface;
+ return NS_NOINTERFACE;
+}
+
+
+// Create a factory object for creating instances of aClass.
+NS_IMETHODIMP
+SampleModule::GetClassObject(nsIComponentManager *aCompMgr,
+ const nsCID&amp; aClass,
+ const nsIID&amp; aIID,
+ void** result)
+{
+
+ if (!kSampleCID.Equals(aClass))
+ return NS_ERROR_FACTORY_NOT_REGISTERED;
+
+ if (!result)
+ return NS_ERROR_INVALID_ARG;
+
+ SampleFactory* factory = new SampleFactory();
+ if (!factory)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ nsresult rv = factory-&gt;QueryInterface(aIID, result);
+
+ if (NS_FAILED(rv)) {
+ *result = nsnull;
+ delete factory;
+ }
+
+ return rv;
+}
+
+
+//----------------------------------------
+
+
+NS_IMETHODIMP
+SampleModule::RegisterSelf(nsIComponentManager *aCompMgr,
+ nsIFile* aPath,
+ const char* registryLocation,
+ const char* componentType)
+{
+
+ nsIComponentRegistrar* compReg = nsnull;
+
+ nsresult rv =
+ aCompMgr-&gt;QueryInterface(kIComponentRegistrarIID, (void**)&amp;compReg);
+ if (NS_FAILED(rv))
+ return rv;
+
+ rv = compReg-&gt;RegisterFactoryLocation(kSampleCID,
+ "Sample Class",
+ nsnull,
+ aPath,
+ registryLocation,
+ componentType);
+
+ compReg-&gt;Release();
+
+ return rv;
+}
+
+NS_IMETHODIMP
+SampleModule::UnregisterSelf(nsIComponentManager* aCompMgr,
+ nsIFile* aPath,
+ const char* registryLocation)
+{
+
+ nsIComponentRegistrar* compReg = nsnull;
+
+ nsresult rv = aCompMgr-&gt;QueryInterface(kIComponentRegistrarIID, (void**)&amp;compReg);
+ if (NS_FAILED(rv))
+ return rv;
+
+ rv = compReg-&gt;UnregisterFactoryLocation(kSampleCID, aPath);
+
+ compReg-&gt;Release();
+
+ return rv;
+}
+
+NS_IMETHODIMP
+SampleModule::CanUnload(nsIComponentManager *aCompMgr, PRBool *okToUnload)
+{
+ *okToUnload = PR_FALSE; // we do not know how to unload.
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------
+
+extern "C" NS_EXPORT nsresult NSGetModule(nsIComponentManager *servMgr,
+ nsIFile* location,
+ nsIModule** return_cobj)
+{
+ nsresult rv = NS_OK;
+
+ // Create and initialize the module instance
+ SampleModule *m = new SampleModule();
+ if (!m) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ // Increase refcnt and store away nsIModule interface to m in return_cobj
+ rv = m-&gt;QueryInterface(kIModuleIID, (void**)return_cobj);
+ if (NS_FAILED(rv)) {
+ delete m;
+ }
+ return rv;
+}
+</pre>
+
+<ol>
+ <li><div class="blockIndicator note"><strong>Note:</strong> non-null-out</div> The <code>CreateInstance</code> method guarantees that if the out variable is non-null, it is valid.</li>
+</ol>
+
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/Creating_XPCOM_Components:Component_Internals" style="float: left;">« 上一页</a><a href="/zh-CN/docs/Creating_XPCOM_Components:Using_XPCOM_Utilities_to_Make_Things_Easier">下一页 »</a></p>
+</div> <p></p><div class="licenseblock">
+<p>Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the <a class="external" href="http://www.opencontent.org/openpub/" rel="noopener">Open Publication License</a>, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.</p>
+</div><p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/finishing_the_component/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/finishing_the_component/index.html
new file mode 100644
index 0000000000..3be93d89f5
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/finishing_the_component/index.html
@@ -0,0 +1,337 @@
+---
+title: Finishing the Component
+slug: Mozilla/Tech/XPCOM/Guide/Creating_components/Finishing_the_Component
+tags:
+ - XPCOM
+ - 所有分类
+translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/Finishing_the_Component
+---
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/Creating_XPCOM_Components:Starting_WebLock" style="float: left;">« 上一页</a><a href="/zh-CN/docs/Creating_XPCOM_Components:Building_the_WebLock_UI">下一页 »</a></p>
+</div><p></p>
+
+<p>At this point you have created most of the infrastructure of the component. The component will be recognized by XPCOM and registered with the Category Manager so that it starts up when XPCOM initializes. When the component starts up, it populates a list of URLs read in from a file stored next to the Gecko binary on the local system.</p>
+
+<h3 id="Using_Frozen_Interfaces" name="Using_Frozen_Interfaces">Using Frozen Interfaces</h3>
+
+<p>The core functionality of blocking sites is still missing, however. The interfaces needed to block certain URLs from loading are not frozen, and there is still some debate about how exactly this functionality should be exposed to embedders and component developers, so the APIs are not ready to be published. This puts you in the same situation as many developers using Mozilla - you want to use some specific functionality, but the interfaces seem to change on a daily basis.</p>
+
+<p>All of the Mozilla source code is publicly available, and interfaces can be used easily enough. Grab the right headers, use the Component or Service Manager to access the interface you want, and the XPCOM object(s) that implement that interface will do your bidding. With this huge amount of flexibility, however, you lose compatibility. If you use "stuff" that isn't frozen, that stuff is subject to change in future versions of Gecko.</p>
+
+<p>If you want to be protected against changes in Gecko, you must only use interfaces and APIs that are clearly marked as FROZEN. The marking is made in the comments above the interface declaration. For example, take a look at the <code>nsIServiceManager</code>:</p>
+
+<pre>/**
+ * The nsIServiceManager manager interface provides a means to obtain
+ * global services in an application. The service manager depends
+ * on the repository to find and instantiate factories to obtain
+ * services.
+ *
+ * Users of the service manager must first obtain a pointer to the
+ * global service manager by calling NS_GetServiceManager. After that,
+ * they can request specific services by calling GetService.
+ * When they are finished they can NS_RELEASE() the service as usual.
+ *
+ * A user of a service may keep references to particular services
+ * indefinitely and only must call Release when it shuts down.
+ *
+ * @status FROZEN
+ */
+</pre>
+
+<p>These frozen interfaces and functions are part of the Gecko SDK. The rule of thumb is that interfaces outside of the SDK are considered "experimental" or unfrozen. See the following sidebar for information about how frozen and unfrozen interfaces can affect your component development, and for technical details about how interface changes beneath your code can cause havoc.</p>
+
+<div class="side-note">
+<p><span id="The_Danger_of_Using_Unfrozen_Interfaces"><a id="The_Danger_of_Using_Unfrozen_Interfaces"></a><strong>The Danger of Using Unfrozen Interfaces</strong></span></p>
+
+<p>Suppose that you need to use the interface <code>nsIFoo</code> that isn't frozen. You build your component using this interface, and it works great with the version of Gecko that you have tested against. However, some point in the future, the <code>nsIFoo</code> interface requires a major change, and methods are reordered, some are added, others are removed. Moreover, since this interface was never supposed to be used by clients other than Gecko or Mozilla, the maintainers of the interface don't know that it's being used, and don't change the IID of the interface. When your component runs in a version of Gecko in which this interface is updated, your method calls will be routed through a different v-table than the one the component expected, most likely resulting in a crash.</p>
+
+<p>Below, the component is compiled against a version of the <code>nsIFoo</code> interface that has three methods. The component calls the method <code>TestA</code> and passes an integer, 10. This works fine in any Gecko installation where a contract guarantees that the interface that was compiled against has the same signature. However, when this same component is used in a Gecko installation where this interface has changed, the method <code>TestA</code> does not exist in the <code>nsIFoo</code> interface; the first entry in the v-table is in fact <code>IsPrime()</code>. When this method call is made, the code execution treats the <code>IsPrime</code> method as <code>TestA</code>. Needless to say, this is a bad thing. Furthermore, there is no way easy way to realize this error at runtime.</p>
+
+<p><img alt="Image:vtable-of-altered-interface.png"></p>
+
+<p>Gecko developers could change the interface's IID, and some do. This can prevent many errors like this. But unfrozen interfaces are not supported in any formal way, and relying upon a different IID for any change in the interface is not a good idea either.</p>
+
+<p>When using frozen interfaces, you are guaranteed compatibility with future versions of Gecko. The only trouble occurs when the compiler itself changes its v-table layout, which can happen when the compiler changes its ABI. For example, in 2002 the GNU Compiler Collection (GCC), version 3.2 changed the C++ ABI, and this caused problems between libraries compiled with GCC 3.2 and applications compiled with an earlier version and vice versa. Similar problems occurred with GCC 4.0, which underwent similar ABI changes.</p>
+</div>
+
+<p>Before attempting to use unfrozen interfaces, you should contact the developers who are responsible for the code you're trying to use (i.e.,<em><a class="external" href="http://www.mozilla.org/owners.html">module owners</a></em> ) and ask them how best to do what you are trying to do. Be as precise you possibly can. They may be able to suggest a supported alternative, or they may be able to notify you about pending changes.</p>
+
+<p>The interface that we need for this project is something called <code>nsIContentPolicy</code>. At the time this book was written, this interface was under review. An interface reaches this state when a group of module owners and peers are actively engaged in discussion about how best to expose it. Usually there are only minor changes to interfaces marked with such a tag. Even with interfaces marked "under review," however, it's still a good idea to contact the module owners responsible for the interfaces you are interested in using.</p>
+
+<h4 id="Copying_Interfaces_into_Your_Build_Environment" name="Copying_Interfaces_into_Your_Build_Environment">Copying Interfaces into Your Build Environment</h4>
+
+<p>To get and implement interfaces that are not part of Gecko in your component, simply create a new directory in the Gecko SDK named <code>unfrozen</code>. Copy the headers and IDL files that you need from the <code><a href="https://dxr.mozilla.org/mozilla-central/source/content/base/public" rel="custom">content/base/public</a></code> source directory of the Gecko build into this new directory. (For <strong>WebLock</strong>, all you need are the headers for <code>nsIContentPolicy</code> and the <code>nsIContentPolicy.idl</code>.) Then, using the same steps you used to create the <code>Weblock.h</code>, create a header from this IDL file using the xpidl compiler. Once you have these interface and header files, you can modify the <code>WebLock</code> class to implement the <code>nsIContentPolicy</code> interface. The Weblock class will then support four interfaces: <code>nsISupports</code>, <code>nsIObserver</code>, <code>nsIContentPolicy</code>, and <code>iWeblock</code>.</p>
+
+<p><img alt="Image:weblock-implemented-ifaces.png"></p>
+
+<p><span id="%3Ccode%3EWebLock%3C/code%3E_Interfaces"><a id="%3Ccode%3EWebLock%3C/code%3E_Interfaces"></a><strong><code>WebLock</code> Interfaces</strong></span></p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">Interface Name</td>
+ <td class="header">Defined by</td>
+ <td class="header">Status</td>
+ <td class="header">Summary</td>
+ </tr>
+ <tr>
+ <td><code>nsISupports</code></td>
+ <td>XPCOM</td>
+ <td>Frozen</td>
+ <td>Provides interface discovery, and object reference counting</td>
+ </tr>
+ <tr>
+ <td><code>nsIObserver</code></td>
+ <td>XPCOM</td>
+ <td>Frozen</td>
+ <td>Allows messaging passing between objects</td>
+ </tr>
+ <tr>
+ <td><code>nsIContentPolicy</code></td>
+ <td>Content</td>
+ <td>Not Frozen</td>
+ <td>Interface for policy control mechanism</td>
+ </tr>
+ <tr>
+ <td><code>iWeblock</code></td>
+ <td>Web Lock</td>
+ <td>Not Frozen</td>
+ <td>Enables and disables Weblock. Also, provides access to the URL that are whitelisted.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h4 id="Implementing_the_nsIContentPolicy_Interface" name="Implementing_the_nsIContentPolicy_Interface">Implementing the <code>nsIContentPolicy</code> Interface</h4>
+
+<p>To implement the new interface, you must <code>#include</code> the unfrozen <code><a class="internal" href="/en/nsIContentPolicy" title="en/nsIContentPolicy">nsIContentPolicy</a></code>, and you must also make sure the build system can find the file you've brought over. The location of the file and the steps for adding that location to the build system vary depending on how you build this component.</p>
+
+<p>Once you have made sure that your component builds with the new header file, you must derive the <code>Weblock</code> class from the interface <code>nsIContentPolicy</code>, which you can do by simply adding a public declaration when defining the class. At the same time, you can add the macro <code>NS_DECL_NSICONTENTPOLICY</code> to the class declaration that provides all of the methods defined in the interface nsIContentPolicy. The updated <code>WebLock</code> class looks as follows:</p>
+
+<pre>class WebLock: public nsIObserver, public iWeblock, public nsIContentPolicy
+{
+ public:
+ WebLock();
+ virtual ~WebLock();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIOBSERVER
+ NS_DECL_IWEBLOCK
+ NS_DECL_NSICONTENTPOLICY
+
+ private:
+ urlNode* mRootURLNode;
+ PRBool mLocked;
+};
+</pre>
+
+<p>Remember to change the <code>nsISupports</code> implementation macro to include <code>nsIContentPolicy</code> so that other parts of Gecko will know <strong>WebLock</strong> supports the <code>nsIContentPolicy</code> interface without modifying this macro.</p>
+
+<pre>NS_IMPL_ISUPPORTS3(WebLock, nsIObserver, iWeblock, nsIContentPolicy);
+</pre>
+
+<h4 id="Receiving_Notifications" name="Receiving_Notifications">Receiving Notifications</h4>
+
+<p>To receive notifications, you must register as a new category. You have already registered as a category to receive startup notification. This time, the category name to use is "content-policy". To add the <strong>WebLock</strong> component to this category, modify the <code>WebLockRegistration</code> callback function so that it looks like this:</p>
+
+<pre>static NS_METHOD WebLockRegistration(nsIComponentManager *aCompMgr,
+ nsIFile *aPath,
+ const char *registryLocation,
+ const char *componentType,
+ const nsModuleComponentInfo *info)
+{
+ nsresult rv;
+ nsCOMPtr&lt;nsIServiceManager&gt; servman = do_QueryInterface((nsISupports*)aCompMgr, &amp;rv);
+ if (NS_FAILED(rv))
+ return rv;
+
+ nsCOMPtr&lt;nsICategoryManager&gt; catman;
+ servman-&gt;GetServiceByContractID(NS_CATEGORYMANAGER_CONTRACTID,
+ NS_GET_IID(nsICategoryManager),
+ getter_AddRefs(catman));
+ if (NS_FAILED(rv))
+ return rv;
+
+ char* previous = nsnull;
+ rv = catman-&gt;AddCategoryEntry("xpcom-startup",
+ "WebLock",
+ WebLock_ContractID,
+ PR_TRUE,
+ PR_TRUE,
+ &amp;previous);
+ if (previous)
+ nsMemory::Free(previous);
+
+ rv = catman-&gt;AddCategoryEntry("content-policy",
+ "WebLock",
+ WebLock_ContractID,
+ PR_TRUE,
+ PR_TRUE,
+ &amp;previous);
+ if (previous)
+ nsMemory::Free(previous);
+ return rv;
+}
+</pre>
+
+<p>This code adds a new category entry under the topic "content-policy," and it calls <code>AddCategoryEntry</code> in the same way we did in <a href="cn/Creating_XPCOM_Components/Starting_WebLock#Registering_for_Notifications">Registering for Notifications</a>. A similar step is required for unregistration.</p>
+
+<h3 id="Implementing_the_nsIContentPolicy" name="Implementing_the_nsIContentPolicy">Implementing the <code>nsIContentPolicy</code></h3>
+
+<p>At this point, you can take the <strong>WebLock</strong> component and install it into a Gecko installation. When the component is loaded, Gecko calls the <code>nsIContentPolicy</code> implementation in <strong>WebLock</strong> on every page load, and this prevents pages from displaying by returning the proper value when the load method is called.</p>
+
+<p>The web locking policy that we are going to put into place is quite simple: for every load request that comes through, we will ensure that the URI is in the list of "good" URLs on the white list.</p>
+
+<div class="side-note">
+<p>If you care to extend this implementation so that the list of URLs is held remotely on a server somewhere - as might be the case when the <strong>WebLock</strong> component is used in a corporate intranet, for example - there are Networking APIs in Gecko that will support this. Or you could implement the web lock so that instead of blocking any site, the component would simply log all URLs that are loaded. In any case, the process to make the XPCOM component is the same.</p>
+</div>
+
+<p>The method that handles the check before page loading and the only method we care about in our own implementation of <code>nsIContentPolicy</code> is <code>ShouldLoad()</code>. The other method on the <code>nsIContentPolicy</code> interface is for blocking processing of specific elements in a document, but our policy is more restrictive: if the URL isn't on the white list, the entire page should be blocked. In the <strong>WebLock</strong> component, the <code>ShouldLoad</code> method looks like this:</p>
+
+<pre>NS_IMETHODIMP WebLock::ShouldLoad(PRInt32 contentType,
+ nsIURI *contentLocation,
+ nsISupports *ctxt,
+ nsIDOMWindow *window,
+ PRBool *_retval)
+</pre>
+
+<h4 id="Uniform_Resource_Locators" name="Uniform_Resource_Locators">Uniform Resource Locators</h4>
+
+<p>The method passes in an interface pointer of type <code>nsIURI</code>, which is based on the Uniform Resource Identifier, or URI. This type is defined by the <a class="external" href="http://www.w3.org/">World Wide Web Consortium</a> as:</p>
+
+<ul>
+ <li>The naming scheme of the mechanism used to access the resource.</li>
+ <li>The name of the machine hosting the resource.</li>
+ <li>The name of the resource itself, given as a path.</li>
+</ul>
+
+<p>In this context, URIs are the strings used refer to places or things on the web. This specific form of URI is called a Uniform Resource Locator, or URL. See the <a class="external" href="http://www.w3.org/TR/REC-html40/intro/intro.html">intro to the HTML 4 specification</a> for more information about URIs and URLs.</p>
+
+<p>Gecko encapsulates these identifiers into two interfaces, <code>nsIURI</code> and <code>nsIURL</code>. You can <code>QueryInterface</code> between these two interfaces. The networking library, Necko, deals only with these interfaces when handling requests. When you want to download a file using Necko, for example, all you probably have is a string that represents the URI of the file. When you pass that string to Necko, it creates an object that implements at least the <code>nsIURI</code> interface (and perhaps other interfaces as well).</p>
+
+<p>Currently, the <strong>WebLock</strong> implementation of the <code>ShouldLoad</code> method compares the in parameter with each string in the white list. But it only should do this comparison for remote URLs, because we don't want to block the application from loading local content that it requires, like files it gets via the <code><a class="external" rel="freelink">resource://</a></code> protocol. If URIs of this kind are blocked, then Gecko will not be able to start up, so we'll restrict the content policy to the HTTP and FTP protocols.</p>
+
+<p>Instead of extracting the string <code>spec</code> out of the <code>nsIURI</code> to do a string comparison, which would require you to do the parsing yourself, you can compare the <code>nsIURI</code> objects with each other, as in the following section. This ensures that the URLs are canonical before they are compared.</p>
+
+<h4 id="Checking_the_White_List" name="Checking_the_White_List">Checking the White List</h4>
+
+<p>The <strong>WebLock</strong> implementation of the <code>ShouldLoad</code> method starts by extracting the scheme of the incoming <code>nsIURI</code>. If the scheme isn't "http", "https", or "ftp", it immediately returns true, which continues the loading process unblocked.</p>
+
+<p>These three are the only kinds of URI that <strong>Weblock</strong> will try to block. When it has one, it walks the linked list and creates a new <code>nsIURI</code> object for each string URL in the list. From each object, <code>ShouldLoad()</code> extracts the host and compares it to the URI. If they match, the component allows the load to continue by returning true. If these two strings do not match, then the component returns return false and blocks the load.</p>
+
+<div class="side-note">
+<p><span id="URI_Caching"><a id="URI_Caching"></a><strong>URI Caching</strong></span></p>
+
+<p>Caching the URI would make this method implementation much faster by avoiding the need to create and destroy so many objects. This points out an important drawback of XPCOM, which is that you cannot create an object on the stack.</p>
+
+<p>Creating this many objects is OK in a tight loop if the buffer of memory that holds the contents of the URLs is guaranteed to be valid for the lifetime of the object. But regardless of how optimized the implementation is with respect to is memory usage, a heap allocation will be made for every XPCOM object created.</p>
+</div>
+
+<p>The string comparison with the URL type "http", "https", and "ftp" looks like this:</p>
+
+<pre>nsEmbedCString scheme;
+contentLocation-&gt;GetScheme(scheme);
+
+if (strcmp("http", scheme.get())  != 0 &amp;&amp;
+ strcmp("https", scheme.get()) != 0 &amp;&amp;
+ strcmp("ftp", scheme.get())  != 0)
+{
+ // this isn't a type of URI that we deal with.
+ *_retval = PR_TRUE;
+ return NS_OK;
+}
+</pre>
+
+<h4 id="Creating_nsIURI_Objects" name="Creating_nsIURI_Objects">Creating <code>nsIURI</code> Objects</h4>
+
+<p>To create an <code>nsIURI</code>, use <code>nsIIOService</code>. <code>nsIIOService</code> is the part of the networking library ("necko") that's responsible for kicking off network requests, managing protocols such as http, ftp, or file, and creating <code>nsIURI</code>s. Necko offers tremendous network functionality, but all the <strong>WebLock</strong> component needs is to create the <code>nsIURI</code> object that can be compared with the URIs on the white list.</p>
+
+<p>Use the Service Manager to acquire the <code>nsIIOService</code>. Since this object is going to be used for the life of the component, it can also be cached. A good place to get an <code>nsIIOService</code> is in the component's <code>Observe()</code> method, which already has a pointer to the <code>Service Manager</code>. The code for getting the IO service from the Service Manager looks like this:</p>
+
+<pre>// Get a pointer to the IOService
+rv = servMan-&gt;GetServiceByContractID("@mozilla.org/network/io-service;1",
+ NS_GET_IID(nsIIOService),
+ getter_AddRefs(mIOService));
+</pre>
+
+<p>Once you have this interface pointer, you can easily create <code>nsIURI</code> objects from a string, as in the following snippet:</p>
+
+<pre>nsCOMPtr&lt;nsIURI&gt; uri;
+nsEmbedCString urlString(node-&gt;urlString);
+mIOService-&gt;NewURI(urlString,
+ nsnull,
+ nsnull,
+ getter_AddRefs(uri));
+</pre>
+
+<p>This code wraps a C-string with a <code>nsEmbedCString</code>, which you'll recall is a string class that many of the Gecko APIs require. See <a href="cn/Creating_XPCOM_Components/Using_XPCOM_Utilities_to_Make_Things_Easier#String_Classes_in_XPCOM">String Classes in XPCOM</a> for more information about strings.</p>
+
+<p>Once the URL string is wrapped in a <code>nsEmbedCString</code>, it can be passed to the method <code>NewURI</code>. This method expects to parse the incoming string and create an object which implements an <code>nsIURI</code> interface. The two <code>nsnull</code> parameters passed to <code>NewURI</code> are used to specify the charset of the string and any base URI to use, respectively. We are assuming here that the charset of the URL string is <a href="cn/UTF-8">UTF-8</a>, and also assuming that every URL string is absolute. See the <a class="external" href="http://www.w3.org/TR/REC-html40/intro/intro.html">intro to the HTML 4 specification</a> for more information about relative URLs.</p>
+
+<p>Here is the complete implementation of the <code>ShouldLoad()</code> method:</p>
+
+<pre>NS_IMETHODIMP
+WebLock::ShouldLoad(PRInt32 contentType,
+ nsIURI *contentLocation,
+ nsISupports *ctxt,
+ nsIDOMWindow *window,
+ PRBool *_retval)
+{
+ if (!contentLocation)
+ return NS_ERROR_FAILURE;
+
+
+ nsEmbedCString scheme;
+ contentLocation-&gt;GetScheme(scheme);
+
+ if (strcmp("http", scheme.get())  != 0 &amp;&amp;
+ strcmp("https", scheme.get()) != 0 &amp;&amp;
+ strcmp("ftp", scheme.get())  != 0)
+ {
+ // this isn't a type of URI that we deal with
+ *_retval = PR_TRUE;
+ return NS_OK;
+ }
+
+ nsEmbedCString hostToLoad;
+ contentLocation-&gt;GetHost(hostToLoad);
+
+ // Assume failure. Do not allow this nsIURI to load.
+ *_retval = PR_FALSE;
+
+ nsresult rv;
+
+ urlNode* node = mRootURLNode;
+ PRBool match = PR_FALSE;
+
+ while (node)
+ {
+ nsCOMPtr&lt;nsIURI&gt; uri;
+ nsEmbedCString urlString(node-&gt;urlString);
+ rv = mIOService-&gt;NewURI(urlString, nsnull, nsnull, getter_AddRefs(uri));
+
+ // if anything bad happens, just abort
+ if (NS_FAILED(rv))
+ return rv;
+
+ nsEmbedCString host;
+ uri-&gt;GetHost(host);
+
+ if (strcmp(hostToLoad.get(), host.get()) == 0)
+ {
+ // match found. Allow this nsIURI to load
+ *_retval = PR_TRUE;
+ return NS_OK;
+ }
+ node = node-&gt;next;
+ }
+ return NS_OK;
+}
+</pre>
+
+<p>At this point, all of the backend work is complete. You can of course improve this backend in many ways, but this example presents the basic creation of what is commonly referred to as a "browser helper object" like <strong>WebLock</strong>. The next chapter looks at how to tie this into the front end - specifically, how to use XPConnect to access and control this component from JavaScript in the user interface.</p>
+
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/Creating_XPCOM_Components:Starting_WebLock" style="float: left;">« 上一页</a><a href="/zh-CN/docs/Creating_XPCOM_Components:Building_the_WebLock_UI">下一页 »</a></p>
+</div> <p></p><div class="licenseblock">
+<p>Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the <a class="external" href="http://www.opencontent.org/openpub/" rel="noopener">Open Publication License</a>, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.</p>
+</div><p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/index.html
new file mode 100644
index 0000000000..13fd6aff60
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/index.html
@@ -0,0 +1,278 @@
+---
+title: 创建_XPCOM_组件
+slug: Mozilla/Tech/XPCOM/Guide/Creating_components
+tags:
+ - XPCOM
+ - 'XPCOM:索引'
+ - 所有分类
+translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components
+---
+<p> </p>
+
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/创建_XPCOM_组件:前言">下一页 »</a></p>
+</div><p></p>
+
+<h3 id=".E5.89.8D.E8.A8.80" name=".E5.89.8D.E8.A8.80"><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%89%8D%E8%A8%80" title="cn/创建_XPCOM_组件/前言">前言</a></h3>
+
+<dl>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%89%8D%E8%A8%80#.E8.B0.81.E8.AF.A5.E8.AF.BB.E8.BF.99.E6.9C.AC.E4.B9.A6" title="cn/创建_XPCOM_组件/前言#.E8.B0.81.E8.AF.A5.E8.AF.BB.E8.BF.99.E6.9C.AC.E4.B9.A6">谁该读这本书</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%89%8D%E8%A8%80#.E6.9C.AC.E6.95.99.E7.A8.8B.E7.9A.84.E7.BB.84.E7.BB.87" title="cn/创建_XPCOM_组件/前言#.E6.9C.AC.E6.95.99.E7.A8.8B.E7.9A.84.E7.BB.84.E7.BB.87">本教程的组织</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%89%8D%E8%A8%80#.E6.8C.89.E7.85.A7.E4.BE.8B.E5.AD.90.E6.9D.A5.E5.AD.A6.E4.B9.A0" title="cn/创建_XPCOM_组件/前言#.E6.8C.89.E7.85.A7.E4.BE.8B.E5.AD.90.E6.9D.A5.E5.AD.A6.E4.B9.A0">按照例子来学习</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%89%8D%E8%A8%80#.E6.9C.AC.E4.B9.A6.E7.9A.84.E4.BD.93.E4.BE.8B" title="cn/创建_XPCOM_组件/前言#.E6.9C.AC.E4.B9.A6.E7.9A.84.E4.BD.93.E4.BE.8B">本书的体例</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%89%8D%E8%A8%80#.E8.87.B4.E8.B0.A2" title="cn/创建_XPCOM_组件/前言#.E8.87.B4.E8.B0.A2">致谢</a></dd>
+</dl>
+
+<h3 id="XPCOM_.E7.AE.80.E4.BB.8B" name="XPCOM_.E7.AE.80.E4.BB.8B"><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/XPCOM_%E7%AE%80%E4%BB%8B" title="cn/创建_XPCOM_组件/XPCOM_简介">XPCOM 简介</a></h3>
+
+<dl>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/XPCOM_%E7%AE%80%E4%BB%8B#XPCOM_.E8.A7.A3.E5.86.B3.E6.96.B9.E6.A1.88" title="cn/创建_XPCOM_组件/XPCOM_简介#XPCOM_.E8.A7.A3.E5.86.B3.E6.96.B9.E6.A1.88">XPCOM 解决方案</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/XPCOM_%E7%AE%80%E4%BB%8B#Gecko" title="cn/创建_XPCOM_组件/XPCOM_简介#Gecko">Gecko</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/XPCOM_%E7%AE%80%E4%BB%8B#.E7.BB.84.E4.BB.B6" title="cn/创建_XPCOM_组件/XPCOM_简介#.E7.BB.84.E4.BB.B6">组件</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/XPCOM_%E7%AE%80%E4%BB%8B#.E6.8E.A5.E5.8F.A3" title="cn/创建_XPCOM_组件/XPCOM_简介#.E6.8E.A5.E5.8F.A3">接口</a>
+ <dl>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/XPCOM_%E7%AE%80%E4%BB%8B#.E6.8E.A5.E5.8F.A3.E4.B8.8E.E5.B0.81.E8.A3.85" title="cn/创建_XPCOM_组件/XPCOM_简介#.E6.8E.A5.E5.8F.A3.E4.B8.8E.E5.B0.81.E8.A3.85">接口与封装</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/XPCOM_%E7%AE%80%E4%BB%8B#nsISupports_.E5.9F.BA.E6.8E.A5.E5.8F.A3" title="cn/创建_XPCOM_组件/XPCOM_简介#nsISupports_.E5.9F.BA.E6.8E.A5.E5.8F.A3"><code>nsISupports</code> 基接口</a></dd>
+ </dl>
+ </dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/XPCOM_%E7%AE%80%E4%BB%8B#XPCOM_.E7.9A.84ID" title="cn/创建_XPCOM_组件/XPCOM_简介#XPCOM_.E7.9A.84ID">XPCOM 的ID</a>
+ <dl>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/XPCOM_%E7%AE%80%E4%BB%8B#CID" title="cn/创建_XPCOM_组件/XPCOM_简介#CID">CID</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/XPCOM_%E7%AE%80%E4%BB%8B#.E5.A5.91.E7.BA.A6_ID" title="cn/创建_XPCOM_组件/XPCOM_简介#.E5.A5.91.E7.BA.A6_ID">契约 ID</a></dd>
+ </dl>
+ </dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/XPCOM_%E7%AE%80%E4%BB%8B#.E7.B1.BB.E5.8E.82" title="cn/创建_XPCOM_组件/XPCOM_简介#.E7.B1.BB.E5.8E.82">类厂</a>
+ <dl>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/XPCOM_%E7%AE%80%E4%BB%8B#XPIDL_.E4.B8.8E.E7.B1.BB.E5.9E.8B.E5.BA.93" title="cn/创建_XPCOM_组件/XPCOM_简介#XPIDL_.E4.B8.8E.E7.B1.BB.E5.9E.8B.E5.BA.93">XPIDL 与类型库</a></dd>
+ </dl>
+ </dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/XPCOM_%E7%AE%80%E4%BB%8B#XPCOM_.E6.9C.8D.E5.8A.A1" title="cn/创建_XPCOM_组件/XPCOM_简介#XPCOM_.E6.9C.8D.E5.8A.A1">XPCOM 服务</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/XPCOM_%E7%AE%80%E4%BB%8B#XPCOM_.E7.B1.BB.E5.9E.8B" title="cn/创建_XPCOM_组件/XPCOM_简介#XPCOM_.E7.B1.BB.E5.9E.8B">XPCOM 类型</a>
+ <dl>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/XPCOM_%E7%AE%80%E4%BB%8B#.E6.96.B9.E6.B3.95.E7.B1.BB.E5.9E.8B" title="cn/创建_XPCOM_组件/XPCOM_简介#.E6.96.B9.E6.B3.95.E7.B1.BB.E5.9E.8B">方法类型</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/XPCOM_%E7%AE%80%E4%BB%8B#.E5.BC.95.E7.94.A8.E8.AE.A1.E6.95.B0" title="cn/创建_XPCOM_组件/XPCOM_简介#.E5.BC.95.E7.94.A8.E8.AE.A1.E6.95.B0">引用计数</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/XPCOM_%E7%AE%80%E4%BB%8B#.E7.8A.B6.E6.80.81.E7.A0.81" title="cn/创建_XPCOM_组件/XPCOM_简介#.E7.8A.B6.E6.80.81.E7.A0.81">状态码</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/XPCOM_%E7%AE%80%E4%BB%8B#.E5.8F.98.E9.87.8F.E6.98.A0.E5.B0.84" title="cn/创建_XPCOM_组件/XPCOM_简介#.E5.8F.98.E9.87.8F.E6.98.A0.E5.B0.84">变量映射</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/XPCOM_%E7%AE%80%E4%BB%8B#.E9.80.9A.E7.94.A8_XPCOM_.E9.94.99.E8.AF.AF.E7.A0.81" title="cn/创建_XPCOM_组件/XPCOM_简介#.E9.80.9A.E7.94.A8_XPCOM_.E9.94.99.E8.AF.AF.E7.A0.81">通用 XPCOM 错误码</a></dd>
+ </dl>
+ </dd>
+</dl>
+
+<h3 id=".E4.BD.BF.E7.94.A8_XPCOM_.E7.BB.84.E4.BB.B6" name=".E4.BD.BF.E7.94.A8_XPCOM_.E7.BB.84.E4.BB.B6"><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E4%BD%BF%E7%94%A8_XPCOM_%E7%BB%84%E4%BB%B6" title="cn/创建_XPCOM_组件/使用_XPCOM_组件">使用 XPCOM 组件</a></h3>
+
+<dl>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E4%BD%BF%E7%94%A8_XPCOM_%E7%BB%84%E4%BB%B6#.E7.BB.84.E4.BB.B6.E7.9A.84.E4.BE.8B.E5.AD.90" title="cn/创建_XPCOM_组件/使用_XPCOM_组件#.E7.BB.84.E4.BB.B6.E7.9A.84.E4.BE.8B.E5.AD.90">组件的例子</a>
+
+ <dl>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E4%BD%BF%E7%94%A8_XPCOM_%E7%BB%84%E4%BB%B6#Cookie_.E7.AE.A1.E7.90.86.E5.99.A8" title="cn/创建_XPCOM_组件/使用_XPCOM_组件#Cookie_.E7.AE.A1.E7.90.86.E5.99.A8">Cookie 管理器</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E4%BD%BF%E7%94%A8_XPCOM_%E7%BB%84%E4%BB%B6#WebBrowserFind_.E7.BB.84.E4.BB.B6" title="cn/创建_XPCOM_组件/使用_XPCOM_组件#WebBrowserFind_.E7.BB.84.E4.BB.B6"><strong>WebBrowserFind</strong> 组件</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E4%BD%BF%E7%94%A8_XPCOM_%E7%BB%84%E4%BB%B6#WebLock_.E7.BB.84.E4.BB.B6" title="cn/创建_XPCOM_组件/使用_XPCOM_组件#WebLock_.E7.BB.84.E4.BB.B6"><strong>WebLock</strong> 组件</a></dd>
+ </dl>
+ </dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E4%BD%BF%E7%94%A8_XPCOM_%E7%BB%84%E4%BB%B6#Mozilla_.E4.B8.AD.E4.BD.BF.E7.94.A8.E7.9A.84.E7.BB.84.E4.BB.B6" title="cn/创建_XPCOM_组件/使用_XPCOM_组件#Mozilla_.E4.B8.AD.E4.BD.BF.E7.94.A8.E7.9A.84.E7.BB.84.E4.BB.B6">Mozilla 中使用的组件</a>
+ <dl>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E4%BD%BF%E7%94%A8_XPCOM_%E7%BB%84%E4%BB%B6#.E6.9F.A5.E6.89.BE_Mozilla_.E7.BB.84.E4.BB.B6" title="cn/创建_XPCOM_组件/使用_XPCOM_组件#.E6.9F.A5.E6.89.BE_Mozilla_.E7.BB.84.E4.BB.B6">查找 Mozilla 组件</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E4%BD%BF%E7%94%A8_XPCOM_%E7%BB%84%E4%BB%B6#.E5.9C.A8_Cpp_.E4.BB.A3.E7.A0.81.E4.B8.AD.E4.BD.BF.E7.94.A8_XPCOM_.E7.BB.84.E4.BB.B6" title="cn/创建_XPCOM_组件/使用_XPCOM_组件#.E5.9C.A8_Cpp_.E4.BB.A3.E7.A0.81.E4.B8.AD.E4.BD.BF.E7.94.A8_XPCOM_.E7.BB.84.E4.BB.B6">在 Cpp 代码中使用 XPCOM 组件</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E4%BD%BF%E7%94%A8_XPCOM_%E7%BB%84%E4%BB%B6#XPConnect:_.E5.9C.A8.E8.84.9A.E6.9C.AC.E4.B8.AD.E4.BD.BF.E7.94.A8_XPCOM_.E7.BB.84.E4.BB.B6" title="cn/创建_XPCOM_组件/使用_XPCOM_组件#XPConnect:_.E5.9C.A8.E8.84.9A.E6.9C.AC.E4.B8.AD.E4.BD.BF.E7.94.A8_XPCOM_.E7.BB.84.E4.BB.B6">XPConnect: 在脚本中使用 XPCOM 组件</a></dd>
+ </dl>
+ </dd>
+</dl>
+
+<h3 id=".E7.BB.84.E4.BB.B6.E5.86.85.E5.B9.95" name=".E7.BB.84.E4.BB.B6.E5.86.85.E5.B9.95"><a href="/cn/Creating_XPCOM_Components/Component_Internals" title="cn/Creating_XPCOM_Components/Component_Internals">组件内幕</a></h3>
+
+<dl>
+ <dd><a href="/cn/Creating_XPCOM_Components/Component_Internals#.E7.94.A8Cpp.E4.B9.A6.E5.86.99.E7.BB.84.E4.BB.B6" title="cn/Creating_XPCOM_Components/Component_Internals#.E7.94.A8Cpp.E4.B9.A6.E5.86.99.E7.BB.84.E4.BB.B6">用Cpp书写组件</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Component_Internals#XPCOM.E5.88.9D.E5.A7.8B.E5.8C.96" title="cn/Creating_XPCOM_Components/Component_Internals#XPCOM.E5.88.9D.E5.A7.8B.E5.8C.96">XPCOM初始化</a>
+ <dl>
+ <dd><a href="/cn/Creating_XPCOM_Components/Component_Internals#XPCOM.E6.B3.A8.E5.86.8C.E6.8F.8F.E8.BF.B0" title="cn/Creating_XPCOM_Components/Component_Internals#XPCOM.E6.B3.A8.E5.86.8C.E6.8F.8F.E8.BF.B0">XPCOM注册描述</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Component_Internals#XPCOM.E6.B3.A8.E5.86.8C.E7.9A.84.E6.96.B9.E6.B3.95" title="cn/Creating_XPCOM_Components/Component_Internals#XPCOM.E6.B3.A8.E5.86.8C.E7.9A.84.E6.96.B9.E6.B3.95">XPCOM注册的方法</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Component_Internals#.E8.87.AA.E5.8A.A8.E6.B3.A8.E5.86.8C" title="cn/Creating_XPCOM_Components/Component_Internals#.E8.87.AA.E5.8A.A8.E6.B3.A8.E5.86.8C">自动注册</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Component_Internals#The_Shutdown_Process" title="cn/Creating_XPCOM_Components/Component_Internals#The_Shutdown_Process">The Shutdown Process</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Component_Internals#XPCOM.E7.BB.84.E4.BB.B6.E5.BA.93.E7.9A.84.E4.B8.89.E4.B8.AA.E9.83.A8.E5.88.86" title="cn/Creating_XPCOM_Components/Component_Internals#XPCOM.E7.BB.84.E4.BB.B6.E5.BA.93.E7.9A.84.E4.B8.89.E4.B8.AA.E9.83.A8.E5.88.86">XPCOM组件库的三个部分</a></dd>
+ </dl>
+ </dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Component_Internals#XPCOM_Glue" title="cn/Creating_XPCOM_Components/Component_Internals#XPCOM_Glue">XPCOM Glue</a>
+ <dl>
+ <dd><a href="/cn/Creating_XPCOM_Components/Component_Internals#The_Glue_Library" title="cn/Creating_XPCOM_Components/Component_Internals#The_Glue_Library">The Glue Library</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Component_Internals#XPCOM_String_Classes" title="cn/Creating_XPCOM_Components/Component_Internals#XPCOM_String_Classes">XPCOM String Classes</a></dd>
+ </dl>
+ </dd>
+</dl>
+
+<h3 id=".E5.BB.BA.E7.AB.8B.E7.BB.84.E4.BB.B6.E4.BB.A3.E7.A0.81" name=".E5.BB.BA.E7.AB.8B.E7.BB.84.E4.BB.B6.E4.BB.A3.E7.A0.81"><a href="/cn/Creating_XPCOM_Components/Creating_the_Component_Code" title="cn/Creating_XPCOM_Components/Creating_the_Component_Code">建立组件代码</a></h3>
+
+<dl>
+ <dd><a href="/cn/Creating_XPCOM_Components/Creating_the_Component_Code#.E6.88.91.E4.BB.AC.E5.B0.86.E5.81.9A.E4.BB.80.E4.B9.88" title="cn/Creating_XPCOM_Components/Creating_the_Component_Code#.E6.88.91.E4.BB.AC.E5.B0.86.E5.81.9A.E4.BB.80.E4.B9.88">我们将做什么</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Creating_the_Component_Code#.E7.BB.84.E4.BB.B6.E6.B3.A8.E5.86.8C" title="cn/Creating_XPCOM_Components/Creating_the_Component_Code#.E7.BB.84.E4.BB.B6.E6.B3.A8.E5.86.8C">组件注册</a>
+ <dl>
+ <dd><a href="/cn/Creating_XPCOM_Components/Creating_the_Component_Code#The_regxpcom_Program" title="cn/Creating_XPCOM_Components/Creating_the_Component_Code#The_regxpcom_Program">The <code>regxpcom</code> Program</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Creating_the_Component_Code#.E5.85.B6.E4.BB.96.E7.9A.84.E6.B3.A8.E5.86.8C.E9.80.94.E5.BE.84" title="cn/Creating_XPCOM_Components/Creating_the_Component_Code#.E5.85.B6.E4.BB.96.E7.9A.84.E6.B3.A8.E5.86.8C.E9.80.94.E5.BE.84">其他的注册途径</a></dd>
+ </dl>
+ </dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Creating_the_Component_Code#.E6.A6.82.E8.A7.88WebLock_Module_Source" title="cn/Creating_XPCOM_Components/Creating_the_Component_Code#.E6.A6.82.E8.A7.88WebLock_Module_Source">概览<strong>WebLock</strong> Module Source</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Creating_the_Component_Code#.E6.B7.B1.E5.BA.A6.E6.8C.96.E6.8E.98:_.E9.9C.80.E8.A6.81.E7.9A.84Includes.E5.92.8C.E5.B8.B8.E9.87.8F" title="cn/Creating_XPCOM_Components/Creating_the_Component_Code#.E6.B7.B1.E5.BA.A6.E6.8C.96.E6.8E.98:_.E9.9C.80.E8.A6.81.E7.9A.84Includes.E5.92.8C.E5.B8.B8.E9.87.8F">深度挖掘: 需要的Includes和常量</a>
+ <dl>
+ <dd><a href="/cn/Creating_XPCOM_Components/Creating_the_Component_Code#XPCOM.E4.B8.AD.E7.9A.84.E6.A0.87.E8.AF.86.E7.AC.A6" title="cn/Creating_XPCOM_Components/Creating_the_Component_Code#XPCOM.E4.B8.AD.E7.9A.84.E6.A0.87.E8.AF.86.E7.AC.A6">XPCOM中的标识符</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Creating_the_Component_Code#.E6.B3.A8.E5.86.8C.E8.BF.87.E7.A8.8B.E7.9A.84.E4.BB.A3.E7.A0.81" title="cn/Creating_XPCOM_Components/Creating_the_Component_Code#.E6.B3.A8.E5.86.8C.E8.BF.87.E7.A8.8B.E7.9A.84.E4.BB.A3.E7.A0.81">注册过程的代码</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Creating_the_Component_Code#.E6.B3.A8.E5.86.8C.E7.94.A8.E7.9A.84.E6.96.B9.E6.B3.95" title="cn/Creating_XPCOM_Components/Creating_the_Component_Code#.E6.B3.A8.E5.86.8C.E7.94.A8.E7.9A.84.E6.96.B9.E6.B3.95">注册用的方法</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Creating_the_Component_Code#.E5.BB.BA.E7.AB.8B.E4.BD.A0.E7.9A.84.E7.BB.84.E4.BB.B6.E7.9A.84.E6.8E.A5.E5.8F.A3" title="cn/Creating_XPCOM_Components/Creating_the_Component_Code#.E5.BB.BA.E7.AB.8B.E4.BD.A0.E7.9A.84.E7.BB.84.E4.BB.B6.E7.9A.84.E6.8E.A5.E5.8F.A3">建立你的组件的接口</a></dd>
+ </dl>
+ </dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/%E5%BB%BA%E7%AB%8B%E7%BB%84%E4%BB%B6%E4%BB%A3%E7%A0%81#webLock1.cpp" title="cn/Creating_XPCOM_Components/建立组件代码#webLock1.cpp"><code>webLock1.cpp</code></a></dd>
+</dl>
+
+<h3 id=".E4.BD.BF.E7.94.A8XPCOM.E5.B7.A5.E5.85.B7.E7.B1.BB.E8.AE.A9.E4.BA.8B.E6.83.85.E5.8F.98.E5.BE.97.E7.AE.80.E5.8D.95" name=".E4.BD.BF.E7.94.A8XPCOM.E5.B7.A5.E5.85.B7.E7.B1.BB.E8.AE.A9.E4.BA.8B.E6.83.85.E5.8F.98.E5.BE.97.E7.AE.80.E5.8D.95"><a href="/cn/%E5%88%9B%E5%BB%BAXPCOM%E7%BB%84%E4%BB%B6/%E4%BD%BF%E7%94%A8XPCOM%E5%B7%A5%E5%85%B7%E7%B1%BB%E8%AE%A9%E4%BA%8B%E6%83%85%E5%8F%98%E5%BE%97%E7%AE%80%E5%8D%95" title="cn/创建XPCOM组件/使用XPCOM工具类让事情变得简单">使用XPCOM工具类让事情变得简单</a></h3>
+
+<dl>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BAXPCOM%E7%BB%84%E4%BB%B6/%E4%BD%BF%E7%94%A8XPCOM%E5%B7%A5%E5%85%B7%E7%B1%BB%E8%AE%A9%E4%BA%8B%E6%83%85%E5%8F%98%E5%BE%97%E7%AE%80%E5%8D%95#XPCOM_.E5.AE.8F" title="cn/创建XPCOM组件/使用XPCOM工具类让事情变得简单#XPCOM_.E5.AE.8F">XPCOM 宏</a>
+
+ <dl>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BAXPCOM%E7%BB%84%E4%BB%B6/%E4%BD%BF%E7%94%A8XPCOM%E5%B7%A5%E5%85%B7%E7%B1%BB%E8%AE%A9%E4%BA%8B%E6%83%85%E5%8F%98%E5%BE%97%E7%AE%80%E5%8D%95#.E9.80.9A.E7.94.A8XPCOM.E6.A8.A1.E5.9D.97.E5.AE.8F" title="cn/创建XPCOM组件/使用XPCOM工具类让事情变得简单#.E9.80.9A.E7.94.A8XPCOM.E6.A8.A1.E5.9D.97.E5.AE.8F">通用XPCOM模块宏</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BAXPCOM%E7%BB%84%E4%BB%B6/%E4%BD%BF%E7%94%A8XPCOM%E5%B7%A5%E5%85%B7%E7%B1%BB%E8%AE%A9%E4%BA%8B%E6%83%85%E5%8F%98%E5%BE%97%E7%AE%80%E5%8D%95#.E5.9F.BA.E6.9C.AC.E5.AE.9E.E7.8E.B0.E5.AE.8F" title="cn/创建XPCOM组件/使用XPCOM工具类让事情变得简单#.E5.9F.BA.E6.9C.AC.E5.AE.9E.E7.8E.B0.E5.AE.8F">基本实现宏</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BAXPCOM%E7%BB%84%E4%BB%B6/%E4%BD%BF%E7%94%A8XPCOM%E5%B7%A5%E5%85%B7%E7%B1%BB%E8%AE%A9%E4%BA%8B%E6%83%85%E5%8F%98%E5%BE%97%E7%AE%80%E5%8D%95#.E5.A3.B0.E6.98.8E.E5.AE.8F" title="cn/创建XPCOM组件/使用XPCOM工具类让事情变得简单#.E5.A3.B0.E6.98.8E.E5.AE.8F">声明宏</a></dd>
+ </dl>
+ </dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BAXPCOM%E7%BB%84%E4%BB%B6/%E4%BD%BF%E7%94%A8XPCOM%E5%B7%A5%E5%85%B7%E7%B1%BB%E8%AE%A9%E4%BA%8B%E6%83%85%E5%8F%98%E5%BE%97%E7%AE%80%E5%8D%95#webLock2.cpp" title="cn/创建XPCOM组件/使用XPCOM工具类让事情变得简单#webLock2.cpp"><code>webLock2.cpp</code></a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BAXPCOM%E7%BB%84%E4%BB%B6/%E4%BD%BF%E7%94%A8XPCOM%E5%B7%A5%E5%85%B7%E7%B1%BB%E8%AE%A9%E4%BA%8B%E6%83%85%E5%8F%98%E5%BE%97%E7%AE%80%E5%8D%95#XPCOM.E4.B8.AD.E7.9A.84.E5.AD.97.E7.AC.A6.E4.B8.B2.E7.B1.BB" title="cn/创建XPCOM组件/使用XPCOM工具类让事情变得简单#XPCOM.E4.B8.AD.E7.9A.84.E5.AD.97.E7.AC.A6.E4.B8.B2.E7.B1.BB">XPCOM中的字符串类</a>
+ <dl>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BAXPCOM%E7%BB%84%E4%BB%B6/%E4%BD%BF%E7%94%A8XPCOM%E5%B7%A5%E5%85%B7%E7%B1%BB%E8%AE%A9%E4%BA%8B%E6%83%85%E5%8F%98%E5%BE%97%E7%AE%80%E5%8D%95#.E4.BD.BF.E7.94.A8.E5.AD.97.E7.AC.A6.E4.B8.B2" title="cn/创建XPCOM组件/使用XPCOM工具类让事情变得简单#.E4.BD.BF.E7.94.A8.E5.AD.97.E7.AC.A6.E4.B8.B2">使用字符串</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BAXPCOM%E7%BB%84%E4%BB%B6/%E4%BD%BF%E7%94%A8XPCOM%E5%B7%A5%E5%85%B7%E7%B1%BB%E8%AE%A9%E4%BA%8B%E6%83%85%E5%8F%98%E5%BE%97%E7%AE%80%E5%8D%95#nsEmbedString_.E5.92.8C_nsEmbedCString" title="cn/创建XPCOM组件/使用XPCOM工具类让事情变得简单#nsEmbedString_.E5.92.8C_nsEmbedCString"><code>nsEmbedString</code> 和 <code>nsEmbedCString</code></a></dd>
+ </dl>
+ </dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BAXPCOM%E7%BB%84%E4%BB%B6/%E4%BD%BF%E7%94%A8XPCOM%E5%B7%A5%E5%85%B7%E7%B1%BB%E8%AE%A9%E4%BA%8B%E6%83%85%E5%8F%98%E5%BE%97%E7%AE%80%E5%8D%95#.E6.99.BA.E8.83.BD.E6.8C.87.E9.92.88" title="cn/创建XPCOM组件/使用XPCOM工具类让事情变得简单#.E6.99.BA.E8.83.BD.E6.8C.87.E9.92.88">智能指针</a></dd>
+</dl>
+
+<h3 id=".E5.BC.80.E5.A7.8BWebLock" name=".E5.BC.80.E5.A7.8BWebLock"><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock" title="cn/创建_XPCOM_组件/开始WebLock">开始<strong>WebLock</strong></a></h3>
+
+<dl>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#.E5.90.AF.E5.8A.A8.E6.97.B6.E8.A2.AB.E8.B0.83.E7.94.A8" title="cn/创建_XPCOM_组件/开始WebLock#.E5.90.AF.E5.8A.A8.E6.97.B6.E8.A2.AB.E8.B0.83.E7.94.A8">启动时被调用</a>
+
+ <dl>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#.E6.B3.A8.E5.86.8C.E5.88.B0.E6.B6.88.E6.81.AF" title="cn/创建_XPCOM_组件/开始WebLock#.E6.B3.A8.E5.86.8C.E5.88.B0.E6.B6.88.E6.81.AF">注册到消息</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#.E8.AE.BF.E9.97.AECategory_Manager" title="cn/创建_XPCOM_组件/开始WebLock#.E8.AE.BF.E9.97.AECategory_Manager">访问Category Manager</a></dd>
+ </dl>
+ </dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#.E6.8F.90.E4.BE.9BWebLock.E8.AE.BF.E9.97.AE" title="cn/创建_XPCOM_组件/开始WebLock#.E6.8F.90.E4.BE.9BWebLock.E8.AE.BF.E9.97.AE">提供<strong>WebLock</strong>访问</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#.E5.BB.BA.E7.AB.8BWebLock.E7.BC.96.E7.A8.8B.E6.8E.A5.E5.8F.A3" title="cn/创建_XPCOM_组件/开始WebLock#.E5.BB.BA.E7.AB.8BWebLock.E7.BC.96.E7.A8.8B.E6.8E.A5.E5.8F.A3">建立<strong>WebLock</strong>编程接口</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#.E5.9C.A8XPIDL.E4.B8.AD.E5.AE.9A.E4.B9.89WebLock.E6.8E.A5.E5.8F.A3" title="cn/创建_XPCOM_组件/开始WebLock#.E5.9C.A8XPIDL.E4.B8.AD.E5.AE.9A.E4.B9.89WebLock.E6.8E.A5.E5.8F.A3">在XPIDL中定义<strong>WebLock</strong>接口</a>
+ <dl>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#XPIDL.E4.B9.A6.E5.86.99.E6.A0.BC.E5.BC.8F" title="cn/创建_XPCOM_组件/开始WebLock#XPIDL.E4.B9.A6.E5.86.99.E6.A0.BC.E5.BC.8F">XPIDL书写格式</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#.E8.84.9A.E6.9C.AC.E5.8C.96.E6.8E.A5.E5.8F.A3" title="cn/创建_XPCOM_组件/开始WebLock#.E8.84.9A.E6.9C.AC.E5.8C.96.E6.8E.A5.E5.8F.A3">脚本化接口</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#.E5.AE.9E.E7.8E.B0nsISupports" title="cn/创建_XPCOM_组件/开始WebLock#.E5.AE.9E.E7.8E.B0nsISupports">实现<code>nsISupports</code></a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#Web_Locking_.E6.8E.A5.E5.8F.A3" title="cn/创建_XPCOM_组件/开始WebLock#Web_Locking_.E6.8E.A5.E5.8F.A3">Web Locking 接口</a></dd>
+ </dl>
+ </dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#.E5.AE.9E.E7.8E.B0WebLock" title="cn/创建_XPCOM_组件/开始WebLock#.E5.AE.9E.E7.8E.B0WebLock">实现<strong>WebLock</strong></a>
+ <dl>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#.E5.A3.B0.E6.98.8E.E5.AE.8F" title="cn/创建_XPCOM_组件/开始WebLock#.E5.A3.B0.E6.98.8E.E5.AE.8F">声明宏</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#.E5.9C.A8XPCOM.E4.B8.AD.E8.A1.A8.E8.BE.BE.E8.BF.94.E5.9B.9E.E5.80.BC" title="cn/创建_XPCOM_组件/开始WebLock#.E5.9C.A8XPCOM.E4.B8.AD.E8.A1.A8.E8.BE.BE.E8.BF.94.E5.9B.9E.E5.80.BC">在XPCOM中表达返回值</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#XPIDL.E4.BB.A3.E7.A0.81.E7.94.9F.E6.88.90" title="cn/创建_XPCOM_组件/开始WebLock#XPIDL.E4.BB.A3.E7.A0.81.E7.94.9F.E6.88.90">XPIDL代码生成</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#.E4.BB.8E.E5.AE.A2.E6.88.B7.E7.AB.AF.E8.8E.B7.E5.8F.96WebLock_Service" title="cn/创建_XPCOM_组件/开始WebLock#.E4.BB.8E.E5.AE.A2.E6.88.B7.E7.AB.AF.E8.8E.B7.E5.8F.96WebLock_Service">从客户端获取WebLock Service</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#.E5.AE.9E.E7.8E.B0iWebLock.E6.8E.A5.E5.8F.A3" title="cn/创建_XPCOM_组件/开始WebLock#.E5.AE.9E.E7.8E.B0iWebLock.E6.8E.A5.E5.8F.A3">实现<code>iWebLock</code>接口</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#The_Directory_Service" title="cn/创建_XPCOM_组件/开始WebLock#The_Directory_Service">The Directory Service</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#.E7.94.A8nsIFile.E6.94.B9.E5.8F.98.E8.B7.AF.E5.BE.84" title="cn/创建_XPCOM_组件/开始WebLock#.E7.94.A8nsIFile.E6.94.B9.E5.8F.98.E8.B7.AF.E5.BE.84">用<code>nsIFile</code>改变路径</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#.E7.94.A8nsIFile.E6.93.8D.E4.BD.9C.E6.96.87.E4.BB.B6" title="cn/创建_XPCOM_组件/开始WebLock#.E7.94.A8nsIFile.E6.93.8D.E4.BD.9C.E6.96.87.E4.BB.B6">用<code>nsIFile</code>操作文件</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#.E7.94.A8nsILocalFile.E8.AF.BB.E5.8F.96.E6.95.B0.E6.8D.AE" title="cn/创建_XPCOM_组件/开始WebLock#.E7.94.A8nsILocalFile.E8.AF.BB.E5.8F.96.E6.95.B0.E6.8D.AE">用<code>nsILocalFile</code>读取数据</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#.E5.A4.84.E7.90.86White_List_Data" title="cn/创建_XPCOM_组件/开始WebLock#.E5.A4.84.E7.90.86White_List_Data">处理White List Data</a></dd>
+ </dl>
+ </dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#iWebLock.E6.96.B9.E6.B3.95.E5.88.97.E4.B8.BE" title="cn/创建_XPCOM_组件/开始WebLock#iWebLock.E6.96.B9.E6.B3.95.E5.88.97.E4.B8.BE"><code>iWebLock</code>方法列举</a>
+ <dl>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#Lock_.E5.92.8C_Unlock" title="cn/创建_XPCOM_组件/开始WebLock#Lock_.E5.92.8C_Unlock"><code>Lock</code> and <code>Unlock</code></a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#AddSite" title="cn/创建_XPCOM_组件/开始WebLock#AddSite"><code>AddSite</code></a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#RemoveSite" title="cn/创建_XPCOM_组件/开始WebLock#RemoveSite"><code>RemoveSite</code></a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#SetSites" title="cn/创建_XPCOM_组件/开始WebLock#SetSites"><code>SetSites</code></a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#GetNext" title="cn/创建_XPCOM_组件/开始WebLock#GetNext"><code>GetNext</code></a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#GetSites" title="cn/创建_XPCOM_组件/开始WebLock#GetSites"><code>GetSites</code></a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BC%80%E5%A7%8BWebLock#HasMoreElements" title="cn/创建_XPCOM_组件/开始WebLock#HasMoreElements"><code>HasMoreElements</code></a></dd>
+ </dl>
+ </dd>
+</dl>
+
+<h3 id="Finishing_the_Component" name="Finishing_the_Component"><a href="/cn/Creating_XPCOM_Components/Finishing_the_Component" title="cn/Creating_XPCOM_Components/Finishing_the_Component">Finishing the Component</a></h3>
+
+<dl>
+ <dd><a href="/cn/Creating_XPCOM_Components/Finishing_the_Component#Using_Frozen_Interfaces" title="cn/Creating_XPCOM_Components/Finishing_the_Component#Using_Frozen_Interfaces">Using Frozen Interfaces</a>
+
+ <dl>
+ <dd><a href="/cn/Creating_XPCOM_Components/Finishing_the_Component#Copying_Interfaces_Into_Your_Build_Environment" title="cn/Creating_XPCOM_Components/Finishing_the_Component#Copying_Interfaces_Into_Your_Build_Environment">Copying Interfaces Into Your Build Environment</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Finishing_the_Component#Implementing_the_nsIContentPolicy_Interface" title="cn/Creating_XPCOM_Components/Finishing_the_Component#Implementing_the_nsIContentPolicy_Interface">Implementing the <code>nsIContentPolicy</code> Interface</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Finishing_the_Component#Receiving_Notifications" title="cn/Creating_XPCOM_Components/Finishing_the_Component#Receiving_Notifications">Receiving Notifications</a></dd>
+ </dl>
+ </dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Finishing_the_Component#Implementing_the_nsIContentPolicy" title="cn/Creating_XPCOM_Components/Finishing_the_Component#Implementing_the_nsIContentPolicy">Implementing the <code>nsIContentPolicy</code></a>
+ <dl>
+ <dd><a href="/cn/Creating_XPCOM_Components/Finishing_the_Component#Uniform_Resource_Locators" title="cn/Creating_XPCOM_Components/Finishing_the_Component#Uniform_Resource_Locators">Uniform Resource Locators</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Finishing_the_Component#Checking_the_White_List" title="cn/Creating_XPCOM_Components/Finishing_the_Component#Checking_the_White_List">Checking the White List</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Finishing_the_Component#Creating_nsIURI_Objects" title="cn/Creating_XPCOM_Components/Finishing_the_Component#Creating_nsIURI_Objects">Creating <code>nsIURI</code> Objects</a></dd>
+ </dl>
+ </dd>
+</dl>
+
+<h3 id="Building_the_WebLock_UI" name="Building_the_WebLock_UI"><a href="/cn/Creating_XPCOM_Components/Building_the_WebLock_UI" title="cn/Creating_XPCOM_Components/Building_the_WebLock_UI">Building the <strong>WebLock</strong> UI</a></h3>
+
+<dl>
+ <dd><a href="/cn/Creating_XPCOM_Components/Building_the_WebLock_UI#User_Interface_Package_List" title="cn/Creating_XPCOM_Components/Building_the_WebLock_UI#User_Interface_Package_List">User Interface Package List</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Building_the_WebLock_UI#Client_Code_Overview" title="cn/Creating_XPCOM_Components/Building_the_WebLock_UI#Client_Code_Overview">Client Code Overview</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Building_the_WebLock_UI#XUL" title="cn/Creating_XPCOM_Components/Building_the_WebLock_UI#XUL">XUL</a>
+ <dl>
+ <dd><a href="/cn/Creating_XPCOM_Components/Building_the_WebLock_UI#The_XUL_Document" title="cn/Creating_XPCOM_Components/Building_the_WebLock_UI#The_XUL_Document">The XUL Document</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Building_the_WebLock_UI#The_Locking_UI" title="cn/Creating_XPCOM_Components/Building_the_WebLock_UI#The_Locking_UI">The Locking UI</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Building_the_WebLock_UI#Site_Adding_UI" title="cn/Creating_XPCOM_Components/Building_the_WebLock_UI#Site_Adding_UI">Site Adding UI</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Building_the_WebLock_UI#weblock.xul" title="cn/Creating_XPCOM_Components/Building_the_WebLock_UI#weblock.xul"><code>weblock.xul</code></a></dd>
+ </dl>
+ </dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Building_the_WebLock_UI#Overlaying_New_User_Interface_Into_Mozilla" title="cn/Creating_XPCOM_Components/Building_the_WebLock_UI#Overlaying_New_User_Interface_Into_Mozilla">Overlaying New User Interface Into Mozilla</a>
+ <dl>
+ <dd><a href="/cn/Creating_XPCOM_Components/Building_the_WebLock_UI#webLockOverlay.xul" title="cn/Creating_XPCOM_Components/Building_the_WebLock_UI#webLockOverlay.xul"><code>webLockOverlay.xul</code></a></dd>
+ </dl>
+ </dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Building_the_WebLock_UI#Other_Resources" title="cn/Creating_XPCOM_Components/Building_the_WebLock_UI#Other_Resources">Other Resources</a>
+ <dl>
+ <dd><a href="/cn/Creating_XPCOM_Components/Building_the_WebLock_UI#weblock.css" title="cn/Creating_XPCOM_Components/Building_the_WebLock_UI#weblock.css"><code>weblock.css</code></a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Building_the_WebLock_UI#Image_Resources" title="cn/Creating_XPCOM_Components/Building_the_WebLock_UI#Image_Resources">Image Resources</a></dd>
+ </dl>
+ </dd>
+</dl>
+
+<h3 id=".E6.89.93.E5.8C.85_WebLock" name=".E6.89.93.E5.8C.85_WebLock"><a href="/cn/Creating_XPCOM_Components/Packaging_WebLock" title="cn/Creating_XPCOM_Components/Packaging_WebLock">打包 WebLock</a></h3>
+
+<dl>
+ <dd><a href="/cn/Creating_XPCOM_Components/Packaging_WebLock#Component_Installation_Overview" title="cn/Creating_XPCOM_Components/Packaging_WebLock#Component_Installation_Overview">组件安装预览</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Packaging_WebLock#Archiving_Resources" title="cn/Creating_XPCOM_Components/Packaging_WebLock#Archiving_Resources">资源归档</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Packaging_WebLock#The_WebLock_Installation_Script" title="cn/Creating_XPCOM_Components/Packaging_WebLock#The_WebLock_Installation_Script"><strong>WebLock</strong> 安装脚本</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Packaging_WebLock#The_WebLock_Trigger_Script" title="cn/Creating_XPCOM_Components/Packaging_WebLock#The_WebLock_Trigger_Script"><strong>WebLock</strong> 跟踪脚本</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Packaging_WebLock#Distributing_Your_Component" title="cn/Creating_XPCOM_Components/Packaging_WebLock#Distributing_Your_Component">分发你的组件</a></dd>
+</dl>
+
+<h3 id=".E9.99.84.E5.BD.95_A_-_.E5.BB.BA.E7.AB.8B_Gecko_SDK" name=".E9.99.84.E5.BD.95_A_-_.E5.BB.BA.E7.AB.8B_Gecko_SDK"><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BB%BA%E7%AB%8B_Gecko_SDK" title="cn/创建_XPCOM_组件/建立_Gecko_SDK">附录 A - 建立 Gecko SDK</a></h3>
+
+<dl>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BB%BA%E7%AB%8B_Gecko_SDK#.E4.B8.8B.E8.BD.BD.E5.92.8C.E5.BB.BA.E7.AB.8B_SDK" title="cn/创建_XPCOM_组件/建立_Gecko_SDK#.E4.B8.8B.E8.BD.BD.E5.92.8C.E5.BB.BA.E7.AB.8B_SDK">下载和建立 SDK</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BB%BA%E7%AB%8B_Gecko_SDK#.E7.BC.96.E8.AF.91.E4.B8.80.E4.B8.AA_Microsoft_Visual_Cpp_.E5.B7.A5.E7.A8.8B" title="cn/创建_XPCOM_组件/建立_Gecko_SDK#.E7.BC.96.E8.AF.91.E4.B8.80.E4.B8.AA_Microsoft_Visual_Cpp_.E5.B7.A5.E7.A8.8B">编译一个 Microsoft Visual Cpp 工程</a>
+ <dl>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BB%BA%E7%AB%8B_Gecko_SDK#.E5.88.9B.E5.BB.BA.E4.B8.80.E4.B8.AA.E6.96.B0.E7.9A.84.E5.B7.A5.E7.A8.8B" title="cn/创建_XPCOM_组件/建立_Gecko_SDK#.E5.88.9B.E5.BB.BA.E4.B8.80.E4.B8.AA.E6.96.B0.E7.9A.84.E5.B7.A5.E7.A8.8B">创建一个新的工程</a></dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BB%BA%E7%AB%8B_Gecko_SDK#.E6.8A.8A_Gecko_SDK_.E6.B7.BB.E5.8A.A0.E5.88.B0.E5.B7.A5.E7.A8.8B.E8.AE.BE.E7.BD.AE" title="cn/创建_XPCOM_组件/建立_Gecko_SDK#.E6.8A.8A_Gecko_SDK_.E6.B7.BB.E5.8A.A0.E5.88.B0.E5.B7.A5.E7.A8.8B.E8.AE.BE.E7.BD.AE">把 Gecko SDK 添加到工程设置</a></dd>
+ </dl>
+ </dd>
+ <dd><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BB%BA%E7%AB%8B_Gecko_SDK#Unix_.E4.B8.8B.E7.9A.84.E4.B8.80.E4.B8.AA_Makefile" title="cn/创建_XPCOM_组件/建立_Gecko_SDK#Unix_.E4.B8.8B.E7.9A.84.E4.B8.80.E4.B8.AA_Makefile">Unix 下的一个 Makefile</a></dd>
+</dl>
+
+<h3 id=".E9.99.84.E5.BD.95B_-_.E8.B5.84.E6.BA.90" name=".E9.99.84.E5.BD.95B_-_.E8.B5.84.E6.BA.90"><a href="/cn/Creating_XPCOM_Components/Resources" title="cn/Creating_XPCOM_Components/Resources">附录B - 资源</a></h3>
+
+<dl>
+ <dd><a href="/cn/Creating_XPCOM_Components/Resources#WebLock_Resources" title="cn/Creating_XPCOM_Components/Resources#WebLock_Resources">WebLock 资源</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Resources#Gecko_Resources" title="cn/Creating_XPCOM_Components/Resources#Gecko_Resources">Gecko 资源</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Resources#XPCOM_Resources" title="cn/Creating_XPCOM_Components/Resources#XPCOM_Resources">XPCOM 资源</a></dd>
+ <dd><a href="/cn/Creating_XPCOM_Components/Resources#General_Development_Resources" title="cn/Creating_XPCOM_Components/Resources#General_Development_Resources">General Development 资源</a></dd>
+</dl>
+
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/创建_XPCOM_组件:前言">下一页 »</a></p>
+</div> <p></p><div class="licenseblock">
+<p>Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the <a class="external" href="http://www.opencontent.org/openpub/" rel="noopener">Open Publication License</a>, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.</p>
+</div><p></p>
+
+<p> </p>
+
+<p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/packaging_weblock/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/packaging_weblock/index.html
new file mode 100644
index 0000000000..3a7744ec03
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/packaging_weblock/index.html
@@ -0,0 +1,136 @@
+---
+title: Packaging WebLock
+slug: Mozilla/Tech/XPCOM/Guide/Creating_components/Packaging_WebLock
+tags:
+ - XPCOM
+ - 所有分类
+translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/Packaging_WebLock
+---
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/Creating_XPCOM_Components:Building_the_WebLock_UI" style="float: left;">« 上一页</a><a href="/zh-CN/docs/创建_XPCOM_组件:建立_Gecko_SDK">下一页 »</a></p>
+</div><p></p>
+
+<p>这是教程最后一部分, 我们将把所有的web所有的组件成分打包成可安装到其他应用中的形式 - the library itself, the type library, the header file, and the user interface resources. The first section, <a href="#Component_Installation_Overview">Component Installation Overview</a>, describes the general installation process in Mozilla. The following sections describe the steps you can take to organize the <strong>WebLock</strong> component for distribution and installation.</p>
+
+<div class="side-note">
+<p>请注意: 这个教程主要是关注组件开发本身, 所以这部分描述有关打包和安装到Gecko的过程是很简单的. 如果你希望了解详细的打包和安装组件到基于Gecko应用的信息,应该参考http://www.mozilla.org/projects/xpinstall.</p>
+</div>
+
+<h3 id="Component_Installation_Overview" name="Component_Installation_Overview">Component Installation Overview</h3>
+
+<p>XPInstall是一组JavaScript APIs用来建立安装脚本. 使用XPInstall,你可以为装载到Gecko-based应用,Mozilla extensions,或者individual components的组件建立web-based安装脚本. <strong>WebLock</strong> component安装脚本也可以用来注册组件到browser(see <a href="cn/Creating_XPCOM_Components/Component_Internals#Registration_Methods_in_XPCOM">Registration Methods in XPCOM</a> for more information on registration).</p>
+
+<p>下面的例子安装脚本使用了Mozilla XPInstall技术来操作安装并且以高层次Javascript对象的方式来跟Mozilla's<em>chrome registry</em> 交互。</p>
+
+<div class="side-note">
+<p><span id="What_Is_the_Chrome_Registry?"><a id="What_Is_the_Chrome_Registry?"></a><strong>What Is the Chrome Registry?</strong></span></p>
+
+<p>Like the Windows registry, the chrome registry is a database of information about applications, skins, and other extensions that have been installed in a Gecko application. Since Mozilla and other Gecko-based applications are cross-platform, this database is abstracted above the operating system or any particular platform's registry.</p>
+
+<p>The chrome registry lives in a series of RDF/XML files in the application directory of Mozilla and other Gecko-based browsers, where new installs, user configurable data, skins, and other information are related to one another and the application itself.</p>
+</div>
+
+<p>XPInstall中的JavaScript APIs <code>Install</code> 对象下载包含了安装文件的JAR并且调用注册方法来告诉 Mozilla 新的组件和用来调用<strong>WebLock</strong>组件的UI. <a href="#WebLock_Installation_Script">WebLock Installation Script</a> 是完整的<em>trigger installation script</em> , 可以从网页触发. 文件被存储在JAR file <code>weblock.jar</code>, 这是一个简单的ZIP文件,以XPI结尾,有时候也可能包含一个内部的安装脚本<code>install.js</code>.</p>
+
+<p>一旦你把组件和<strong>Weblock</strong>相关资源正确打包(see the following section, <a href="#Archiving_Resources">Archiving Resources</a>), <strong>WebLock</strong>安装脚本是一个简单的事情(see <a href="#The_WebLock_Installation_Script">The WebLock Installation Script</a>).</p>
+
+<h3 id="Archiving_Resources" name="Archiving_Resources">Archiving Resources</h3>
+
+<p>Once you have compiled all the resources that make up the <strong>WebLock</strong> component and the files that make up the user interface that will be added to the browser, you can place these within a subdirectory called <code>weblock</code>.</p>
+
+<p>Place the entire subdirectory into a ZIP archive and name the archive <code>weblock.xpi</code>. The archive, its subdirectory structure, and its contents should look like this:</p>
+
+<p><span id="%3Ccode%3Eweblock.xpi%3C/code%3E_Archive_Viewed_in_WinZIP"><a id="%3Ccode%3Eweblock.xpi%3C/code%3E_Archive_Viewed_in_WinZIP"></a><strong><code>weblock.xpi</code> Archive Viewed in WinZIP</strong></span></p>
+
+<p><img alt="Image:weblock-zipped-package.png"></p>
+
+<p>Note that the top level of the archive holds the <code>install.js</code> installation file, an RDF manifest for the package as a whole, and the component files (<code>weblock.xpt</code> and <code>weblock4.dll</code>). The component files are copied to the components directory of the Gecko application, and the weblock subdirectory gets copied over into the chrome subdirectory, where its UI resources can be added dynamically to the XUL-based Gecko application.</p>
+
+<p>The next section shows how this process of downloading, copying and registering the necessary files from the XPI can be achieved with an XPInstall installation script.</p>
+
+<h3 id="The_WebLock_Installation_Script" name="The_WebLock_Installation_Script">The <strong>WebLock</strong> Installation Script</h3>
+
+<p>安装脚本是一个存储在XPI中的JavaScript文件. 他必须在包的根目录 (i.e., <code>weblock.xpi</code>) itself. 一旦触发 (see <a href="#The_WebLock_Trigger_Script">The WebLock Trigger Script</a>), 安章脚本将:</p>
+
+<ul>
+ <li>downloads the <strong>WebLock</strong> component and places it in the <code>components</code> directory</li>
+ <li>copies the <code>weblock</code> subdirectory in the Mozilla chrome application subdirectory</li>
+ <li>registers both the component and the UI</li>
+</ul>
+
+<p>The XPInstall API提供了一些核心方法<sup><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Guide/Creating_components/Packaging_WebLock#endnote_essential-methods">[essential-methods]</a></sup>例如 <code>initInstall</code>, <code>registerChrome</code>, <code>addFile</code>, and others.</p>
+
+<p><span id="WebLock_Installation_Script"><a id="WebLock_Installation_Script"></a><strong>WebLock Installation Script</strong></span></p>
+
+<pre>// initialize the installation
+var err = initInstall("WebLock", "weblock", 1.0);
+
+var componentsDir = getFolder("Components");
+var cf = getFolder("Chrome");
+
+// add the DLL and say where it'll go
+addFile("weblock.dll", 1.0, "weblock.dll", componentsDir, "");
+
+// add the typelib also
+addFile("weblock.xpt", "1.0", "weblock.xpt", componentsDir, "");
+
+// add the weblock subdirectory of the XPI and specify that
+// it be installed in the chrome application directory
+err = addDirectory("weblock", "1.0", "", chromeDir, "");
+
+// ? have to register component here or with regxpcom?
+
+// register the new UI with the mozilla chrome registry
+
+registerChrome(CONTENT, getFolder(cf,"weblock.xpi"),"weblock");
+registerChrome(SKIN, getFolder(cf, "weblock.xpi"),"weblock");
+
+// perform the installation if there are no errors
+if (err==SUCCESS)
+ performInstall();
+else
+ cancelInstall(err);
+</pre>
+
+<h3 id="The_WebLock_Trigger_Script" name="The_WebLock_Trigger_Script">The <strong>WebLock</strong> Trigger Script</h3>
+
+<p>The <code>trigger script</code> is the script placed on a web page that actually initiates an XPInstall installation and calls the installation script that appears in the XPI. The following HTML specifies a complete webpage in which the trigger script is defined as a JavaScript function, <code>installWebLock</code>, that gets called when the user clicks the hyperlink.</p>
+
+<pre>&lt;html&gt;
+&lt;title&gt;WebLock Installation&lt;/title&gt;
+&lt;script type="text/javascript"&gt;
+/*
+ * Trigger function that downloads the XPI so the
+ * install.js file inside can be read and executed
+ */
+function installWebLock()
+{
+ weblock_xpi = {'WebLock Extension': 'weblock.xpi'};
+ InstallTrigger.install(weblock_xpi);
+}
+&lt;/script&gt;
+
+&lt;h1&gt;Install WebLock&lt;/h1&gt;
+
+&lt;p&gt;&lt;a href="#" onclick="installWebLock();"&gt;install weblock&lt;/a&gt;&lt;/p&gt;
+
+&lt;/html&gt;
+</pre>
+
+<h3 id="Distributing_Your_Component" name="Distributing_Your_Component">Distributing Your Component</h3>
+
+<p>Once you have the component packaged properly and the necessary installation and trigger scripts, you are ready to distribute your component so others can install it in their Gecko applications.</p>
+
+<p>In Mozilla and Netscape browsers, XPInstall makes this process especially easy by providing the file format (XPI) and the necessary installation scripts for doing a web-based installation. As <a href="#WebLock_Installation_Script">WebLock Installation Script</a> demonstrates, XPInstall uses special keywords to refer to common installation directories such as <code>components</code> in a generalized, cross-platform way.</p>
+
+<p>If you are installing <strong>WebLock</strong> in an Gecko-based application for which XPInstall is not available, then you will have to devise a separate installation scheme. We leave this as an exercise for the reader.</p>
+
+<ol>
+ <li><div class="blockIndicator note"><strong>Note:</strong> install-object-methods</div> The methods are available on the main <code>Install</code> object, which is implied in the script below in the same way that the <code>window</code> object is implied in JavaScript manipulation of the DOM of a web page. In other words, the fragment <code>initInstall()</code> from the script is equivalent to <code>Install.initInstall()</code>.</li>
+</ol>
+
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/Creating_XPCOM_Components:Building_the_WebLock_UI" style="float: left;">« 上一页</a><a href="/zh-CN/docs/创建_XPCOM_组件:建立_Gecko_SDK">下一页 »</a></p>
+</div><p></p><div class="licenseblock">
+<p>Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the <a class="external" href="http://www.opencontent.org/openpub/" rel="noopener">Open Publication License</a>, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.</p>
+</div><p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/preface/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/preface/index.html
new file mode 100644
index 0000000000..0710f0a701
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/preface/index.html
@@ -0,0 +1,83 @@
+---
+title: 前言
+slug: Mozilla/Tech/XPCOM/Guide/Creating_components/Preface
+tags:
+ - XPCOM
+ - 所有分类
+translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/Preface
+---
+<p> </p>
+
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/创建_XPCOM_组件:XPCOM_简介">下一页 »</a></p>
+</div>这本书是关于 Gecko, 以及如何创建基于 Gecko 的 <a href="/cn/XPCOM" title="cn/XPCOM">XPCOM</a> 组件. 尽管本书的重点是放在把你的 C++ 代码制作成一个使用 Gecko 的组件的步骤之上, 我们还希望这个过程能够讨论到所有构建 XPCOM 的相关工具, 技巧和技术. 因此本书的安排上是作为一个参考书, 使读者能够自己创建组件, 学习不同的 XPCOM 内容. 比如说, 导言中包含了什么是组件的讨论; 第一章中你可以编译基本的源码并注册到 Mozilla 中, 由此讨论了组件于模块之间的关系, 以及一般的注册过程.<p></p>
+
+<p>每章的开始会给出这一章的主要内容. Sidebar sections are included to highlight technical details. 在本书的结尾, 如果能够达到本书的目的的话, 读者应该学会如何创建一个组件, Gecko 中的 XPCOM 组件框架.</p>
+
+<h3 id=".E8.B0.81.E8.AF.A5.E8.AF.BB.E8.BF.99.E6.9C.AC.E4.B9.A6" name=".E8.B0.81.E8.AF.A5.E8.AF.BB.E8.BF.99.E6.9C.AC.E4.B9.A6">谁该读这本书</h3>
+
+<p><a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6" title="cn/创建_XPCOM_组件">创建 XPCOM 组件</a> 是为 C++ 开发人员而写. 尽管你可能会使用 <a href="/cn/JavaScript" title="cn/JavaScript">JavaScript</a>, <a href="/cn/C" title="cn/C">C</a> 或其他的语言来创建 XPCOM 组件, 组件管理的实现是采用 C++, 许多关于如何创建 XPCOM 组件的讨论也是从 C++ 语言开始的. 然而并不要求读者是一个 C++ 语言的专家, 你需要了解的是基本的 C++ 继承和封装的思想, 我们在书中将尽可能的解释这些 C++ 语言的特性的使用. 由于 Mozilla 使用 JavaScript 脚本语言来访问 XPCOM 组件, 所以熟悉 JavaScript 会很有帮助.</p>
+
+<p>XPCOM 是 Cross Platform Component Object Model (跨平台组件模型)的缩写. 就象它的名字暗示的, XPCOM 类似于 Microsoft 的 COM. 开发 MS COM 的经验大多都可以被应用到 XPCOM. 然而本书假设读者对 COM 一无所知, 本书将包含关于 COM 基本思想的介绍.</p>
+
+<p>本书将描述一个控制浏览动作的 XPCOM 组件的制作过程. 尽管 XPCOM 的多数应用环境与 web 浏览并没有关系, 但是 XPCOM 现在的主要客户应用是 Gecko, 一个开源的, 遵循标准的嵌入式 web 浏览器, 所以它是最简单的, 而且是最实用的展示 XPCOM 功能的例子. 本教程中关于组件的详细描述在这里 <a href="/cn/Creating_XPCOM_Components/Creating_the_Component_Code#What_We.27ll_Be_Working_On" title="cn/Creating_XPCOM_Components/Creating_the_Component_Code#What_We.27ll_Be_Working_On">What We'll Be Working On</a>.</p>
+
+<h3 id=".E6.9C.AC.E6.95.99.E7.A8.8B.E7.9A.84.E7.BB.84.E7.BB.87" name=".E6.9C.AC.E6.95.99.E7.A8.8B.E7.9A.84.E7.BB.84.E7.BB.87">本教程的组织</h3>
+
+<p>下面的列表给出了编制一个称为 <strong>WebLock</strong> 的 XPCOM 组件的整体步骤, 这个组件向基于 Gecko 的浏览器提供了阻止网站访问的功能. 每个步骤都有各自的章节, 在各个章节中会讨论相关的内容.</p>
+
+<ul>
+ <li>创建组件的通用模块.</li>
+ <li>使用 C++ 宏, 特殊的字符串类以及智能指针来优化代码.</li>
+ <li>为组件定义功能; 为这个功能创建一个 <a href="/cn/XPIDL" title="cn/XPIDL">XPIDL</a> 接口; 生成实现代码, 规格定制的 <strong>WebLock</strong> 接口.</li>
+ <li>完整实现 <strong>WebLock</strong> 组件: <code>nsIContentPolicy</code>, 文件 I/O, 加锁等.</li>
+ <li>创建 WebLock 组件用户接口.</li>
+ <li>为发布和安装 <strong>WebLock</strong> 打包.</li>
+</ul>
+
+<h3 id=".E6.8C.89.E7.85.A7.E4.BE.8B.E5.AD.90.E6.9D.A5.E5.AD.A6.E4.B9.A0" name=".E6.8C.89.E7.85.A7.E4.BE.8B.E5.AD.90.E6.9D.A5.E5.AD.A6.E4.B9.A0">按照例子来学习</h3>
+
+<p>安装 XPCOM 到本地机器上的方法有很多, 如果你已经编译了 Mozilla 1.2 或更高的版本源码, 你就已经有了 XPCOM 框架. 如果你还没有下载 Mozilla 源码, 更简单的方法是下载 Gecko SDK, 它包含了 XPCOM 组件框架的库和工具.</p>
+
+<p>如果有了上面的工具, 你就可以编译自己的组件, 并把这个组件添加到 Gecko 库中. 我们这里讨论的 <strong>WebLock</strong> 组件是一个实用的浏览器扩展, 编译它需要 1.2 或更高版本的 Gecko SDK / Mozilla 源码.</p>
+
+<p>本书假设你使用的是 SDK, 下载 SDK, 编译, 和获取可用于编成的 Gecko 组件的方法在本书的附录, <a href="/cn/%E5%88%9B%E5%BB%BA_XPCOM_%E7%BB%84%E4%BB%B6/%E5%BB%BA%E7%AB%8B_Gecko_SDK" title="cn/创建_XPCOM_组件/建立_Gecko_SDK">建立 Gecko SDK</a>.</p>
+
+<h3 id=".E6.9C.AC.E4.B9.A6.E7.9A.84.E4.BD.93.E4.BE.8B" name=".E6.9C.AC.E4.B9.A6.E7.9A.84.E4.BD.93.E4.BE.8B">本书的体例</h3>
+
+<p>下面列出的是格式化文档的习惯,他们用于本书中特定的信息类型并且让信息检索变得简单。目标是使用尽量少的格式类型,同时能辨别不同的信息类型。</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">Format</td>
+ <td class="header">Description</td>
+ </tr>
+ <tr>
+ <td><strong>bold</strong></td>
+ <td><strong>component names</strong> 显示为粗题文字</td>
+ </tr>
+ <tr>
+ <td><code>monospace</code></td>
+ <td><code>code listings</code>, <code>interface names</code> 和 <code>members</code> of interfaces (e.g., <code>createInstance()</code>) 用monospaced 字体表达. 代码行放在不同的box内. 此外, <code>filenames</code> 和 <code>directories</code> 也用 monospaced 字体.</td>
+ </tr>
+ <tr>
+ <td><em>italic</em></td>
+ <td><em>variables</em> appear in italic. 重要的条目和新的概念第一次在文本中出现的时候也应该是斜体字。这些条目通常会立刻有进一步的解释,或者读者可以在本书的某个地方找到详细的解释。</td>
+ </tr>
+ <tr>
+ <td>link</td>
+ <td>References to other sections and to figures and tables are links to those sections.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id=".E8.87.B4.E8.B0.A2" name=".E8.87.B4.E8.B0.A2">致谢</h3>
+
+<p>Thanks to Peter Lubczynski, John Gaunt, Ellen Evans, and Alec Flett for technical reviews. A special thanks goes to Darin Fisher for his very acute observations, close reading, and attention to detail. </p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/创建_XPCOM_组件:XPCOM_简介">下一页 »</a></p>
+</div><p></p><div class="licenseblock">
+<p>Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the <a class="external" href="http://www.opencontent.org/openpub/" rel="noopener">Open Publication License</a>, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.</p>
+</div><p></p>
+
+<p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/resources/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/resources/index.html
new file mode 100644
index 0000000000..b23e6eb4c2
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/resources/index.html
@@ -0,0 +1,10 @@
+---
+title: 资源
+slug: Mozilla/Tech/XPCOM/Guide/Creating_components/Resources
+translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/Resources
+---
+<p><a href="cn/Link_title">Link title</a>
+ <i>
+ Italic text</i>
+</p>
+<pre class="script">Insert formula here</pre>
diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/setting_up_the_gecko_sdk/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/setting_up_the_gecko_sdk/index.html
new file mode 100644
index 0000000000..3e8c8516e2
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/setting_up_the_gecko_sdk/index.html
@@ -0,0 +1,204 @@
+---
+title: 建立 Gecko SDK
+slug: Mozilla/Tech/XPCOM/Guide/Creating_components/Setting_up_the_Gecko_SDK
+tags:
+ - XPCOM
+ - 所有分类
+translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/Setting_up_the_Gecko_SDK
+---
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/Creating_XPCOM_Components:Packaging_WebLock" style="float: left;">« 上一页</a><a href="/zh-CN/docs/Creating_XPCOM_Components:Resources">下一页 »</a></p>
+</div><p></p>
+
+<p>这一章提供建立 Gecko SDK 的基本方法, 下面会告诉开发人员如何下载和组织 Gecko SDK, 如何象 <em>WebLock</em> 一样创建一个新的组件工程.</p>
+
+<h3 id=".E4.B8.8B.E8.BD.BD.E5.92.8C.E5.BB.BA.E7.AB.8B_SDK" name=".E4.B8.8B.E8.BD.BD.E5.92.8C.E5.BB.BA.E7.AB.8B_SDK">下载和建立 SDK</h3>
+
+<p>Gecko SDK 提供了编译 XPCOM 组件所需要的所有的工具, 头文件和库. SDK 现在有 Windows 和 Linux 两个版本, 其他操作系统上的 SDK 正在开发. SDK 在下面的地址下载:</p>
+
+<ul>
+ <li>Linux: <a class="external" href="http://ftp.mozilla.org/pub/mozilla/releases/mozilla1.4a/gecko-sdk-i686-pc-linux-gnu-1.4a.tar.gz" rel="freelink">http://ftp.mozilla.org/pub/mozilla/r...nu-1.4a.tar.gz</a></li>
+ <li>Windows: <a class="external" href="http://ftp.mozilla.org/pub/mozilla/releases/mozilla1.4a/gecko-sdk-win32-1.4a.zip" rel="freelink">http://ftp.mozilla.org/pub/mozilla/r...win32-1.4a.zip</a></li>
+</ul>
+
+<p>注意版号要大于1.4a. 可以在下面的地址获取更新的 SDK 版本 <a class="external" href="http://ftp.mozilla.org/pub/mozilla/releases/" rel="freelink">http://ftp.mozilla.org/pub/mozilla/releases/</a>.</p>
+
+<p>一旦你下载了SDK, 你可以解压缩到任何合适的目录. 在本附录中, 我们建立Windows Gecko SDK 到 <code>c:\gecko-sdk\</code>. 如果你选择其他的位置, 记得调整这里描述的设置指向这个位置(e.g., in the <a href="#建立一个Microsoft_visual_cpp工程">建立一个Microsoft visual cpp工程</a> 章节) .</p>
+
+<p>当你解压缩SDK,它的目录结构看起来应该是:</p>
+
+<p><span id="Layout_of_the_Extracted_SDK"><a id="Layout_of_the_Extracted_SDK"></a><strong>Layout of the Extracted SDK</strong></span></p>
+
+<p><img alt="Image:sdk-layout.png" class="internal" src="/@api/deki/files/2682/=Sdk-layout.png"></p>
+
+<p>目录分别代表SDK中的不同模块。例如网络通讯的所有头文件放在<code>necko</code>目录中,而所有XPCOM需要的头文件则放在 XPCOM 目录中。 这个目录结构使得编译脚本变得比较复杂(因为会产生很多include路径)但是他帮助把SKD的部分组织得更有条例。</p>
+
+<p>两组顶级头文件是比较特别的。<code>mozilla-config.h</code>列出了SDK中使用的所有define,在你的文件中包含着个头文件会保证你创建的组件和Gecko库使用的相同的define。注意<code>mozilla-config.h</code>可能需要在你的组件代码中第一个被include.</p>
+
+<p>每一个模块的目录都分成三个子目录:</p>
+
+<p><span id="Module_Subdirectories"><a id="Module_Subdirectories"></a><strong>Module Subdirectories</strong></span></p>
+
+<p><img alt="Image:module-directory-subdirs.png" class="internal" src="/@api/deki/files/2669/=Module-directory-subdirs.png"></p>
+
+<p><code>bin</code>目录包含了静态库,动态库, 和一些可能会在开发中使用的tools。<code>idl</code>目录包含了模块所公开的公共的IDL文件。<code>includes</code>目录包含了你的组件使用的C++头文件。</p>
+
+<p>现在我们应该提到XPCOM公开的一组二进制代码文件。下面的列表罗列了可执行的Windows文件名:</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">Application Name</td>
+ <td class="header">Description of functionality</td>
+ </tr>
+ <tr>
+ <td><code>regxpcom.exe</code></td>
+ <td>Registers or Unregisters components with XPCOM</td>
+ </tr>
+ <tr>
+ <td><code>xpidl.exe</code></td>
+ <td>Generates typelib and C++ headers from XPIDL</td>
+ </tr>
+ <tr>
+ <td><code>xpt_dump.exe</code></td>
+ <td>Prints out information about a given typelib</td>
+ </tr>
+ <tr>
+ <td><code>xpt_link.exe</code></td>
+ <td>Combines multiple typelibs into a single typelib</td>
+ </tr>
+ </tbody>
+</table>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">Library Name</td>
+ <td class="header">Description of functionality</td>
+ </tr>
+ <tr>
+ <td><code>xpcomglue.lib</code></td>
+ <td>XPCOM Glue library to be used by xpcom components.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id=".E7.BC.96.E8.AF.91.E4.B8.80.E4.B8.AA_Microsoft_Visual_Cpp_.E5.B7.A5.E7.A8.8B" name=".E7.BC.96.E8.AF.91.E4.B8.80.E4.B8.AA_Microsoft_Visual_Cpp_.E5.B7.A5.E7.A8.8B">编译一个 Microsoft Visual Cpp 工程</h3>
+
+<p>一担你建立了Gecko SDK,你可以创建一个Miscrosoft visual c++项目来处理你基于SDK的组件开发。</p>
+
+<h4 id=".E5.88.9B.E5.BB.BA.E4.B8.80.E4.B8.AA.E6.96.B0.E7.9A.84.E5.B7.A5.E7.A8.8B" name=".E5.88.9B.E5.BB.BA.E4.B8.80.E4.B8.AA.E6.96.B0.E7.9A.84.E5.B7.A5.E7.A8.8B">创建一个新的工程</h4>
+
+<p>启动Visual c++以后,从文件菜单重选择new。然后在新建对话框中选择"Win32 Dynamic-Link Library"。 使用对话框右边的栏目输入你的项目和位置。(这个例子使用了 "SampleGeckoProject"作为问兼并,位置是<code>C:\</code> ).</p>
+
+<p><span id="New_Dialog"><a id="New_Dialog"></a><strong>New Dialog</strong></span></p>
+
+<p><img alt="Image:new-vcpp-project.png" class="internal" src="/@api/deki/files/2671/=New-vcpp-project.png"></p>
+
+<p>选择OK. 在出现的Win32 Dynamic-Link Library 对话框里, 你可以选择缺省的 "An Empty DLL Project" 作为DLL的类型.</p>
+
+<p><img alt="Image:vcpp-dll-dialog.png" class="internal" src="/@api/deki/files/2690/=Vcpp-dll-dialog.png"></p>
+
+<p>选择Finish. Microsoft Studio 将根据你的设定建立一个新的项目并且展开项目开发视图。</p>
+
+<h4 id=".E6.8A.8A_Gecko_SDK_.E6.B7.BB.E5.8A.A0.E5.88.B0.E5.B7.A5.E7.A8.8B.E8.AE.BE.E7.BD.AE" name=".E6.8A.8A_Gecko_SDK_.E6.B7.BB.E5.8A.A0.E5.88.B0.E5.B7.A5.E7.A8.8B.E8.AE.BE.E7.BD.AE">把 Gecko SDK 添加到工程设置</h4>
+
+<p>为了build使用Gecko的所有信息,你还需要进一步修改项目使得它知道在哪里取得Gecko SDK。为了编辑项目设置, 从项目菜单种选择Settings (or press Alt-F7).</p>
+
+<p>大部分你在下面步骤中所做的修改方法都适用于所有项目设置的修改(包括Debug和Optimize)。选择从Setting菜单中选择"All Configurations",出现一个下拉菜单:</p>
+
+<p><img alt="Image:vcpp-project-settings.png" class="internal" src="/@api/deki/files/2692/=Vcpp-project-settings.png"></p>
+
+<p>在C/C++ tab,选择Preprocessor组。在这个窗口里你要添加到Gecko SDK的include路径,以及两个 preprocessor defines:</p>
+
+<ul>
+ <li><code>XPCOM_GLUE</code></li>
+ <li><code>MOZILLA_STRICT_API</code></li>
+</ul>
+
+<p>最起码你要加上include <code>nspr</code>, <code>embedstring</code> 和 <code>string</code> <code>include</code>目录, 和<code>xpcom</code> <code>include</code> 子目录. 如果你的组件适用其他SDK的部分(例如Necko), 你也要添加指向他们的路径.</p>
+
+<p>假定你使用例子项目的路径,这些路径看起来会是:</p>
+
+<ul>
+ <li><code>c:\gecko-sdk\embedstring\include</code></li>
+ <li><code>c:\gecko-sdk\xpcom\include</code></li>
+ <li><code>c:\gecko-sdk\nspr\include</code></li>
+ <li><code>c:\gecko-sdk\string\include</code></li>
+</ul>
+
+<p><img alt="Image:vcpp-project-settings-includes.png" class="internal" src="/@api/deki/files/2691/=Vcpp-project-settings-includes.png"></p>
+
+<p>在C++ language组, 禁止异常处理. 正如在 <a href="/cn/XPCOM%E6%A6%82%E8%A7%88/XPCOM%E4%B8%AD%E7%9A%84%E5%BC%82%E5%B8%B8" title="cn/XPCOM概览/XPCOM中的异常">XPCOM中的异常</a>章节所表明的, 异常处理不支持跨越Interface, 所以使用这个功能将可能在开发中引起问题。</p>
+
+<p><strong>WebLock</strong> 组件需要引用必要的库文件以使用XPCOM Glue. 为添加这些库文件,选择Link tab, 然后选择Input category. 在这个面板上不要连接到 <code>nspr</code>, <code>embedstring</code>和<code>xpcom</code>中的子目录<code>include</code> ,而改用<code>bin</code>子目录.</p>
+
+<p>我们也会连接到一些Object/library 模块中的库:</p>
+
+<ul>
+ <li><code>nspr4.lib</code></li>
+ <li><code>plds4.lib</code></li>
+ <li><code>plc4.lib</code></li>
+ <li><code>embedstring.lib</code></li>
+ <li><code>xpcomglue.lib</code></li>
+</ul>
+
+<p>这些设定看起来会是:</p>
+
+<p><img alt="Image:vcpp-project-settings.png" class="internal" src="/@api/deki/files/2692/=Vcpp-project-settings.png"></p>
+
+<p>最后一个你需要让Gecko SDK在你的项目中设定成功的修改是"Use run-time library" 设定为 "Multithreaded DLL." 因为这个设置是根据其他设定而确定的,你<strong>必须设定Release configuration run-time library 为 release multithreaded DLL runtime, 并且Debug configuration 设定为 the debug multithreaded dll runtime</strong> (这个需要澄清一下):</p>
+
+<p><img alt="Image:vcpp-runtime-settings.png" class="internal" src="/@api/deki/files/2693/=Vcpp-runtime-settings.png"></p>
+
+<p>完成所有这些设定后,选择OK. 这就完成了项目设定并且让你的项目能包含和编译XPCOM组件.</p>
+
+<h3 id="Unix_.E4.B8.8B.E7.9A.84.E4.B8.80.E4.B8.AA_Makefile" name="Unix_.E4.B8.8B.E7.9A.84.E4.B8.80.E4.B8.AA_Makefile">Unix 下的一个 Makefile</h3>
+
+<p>Linux 下不采用工程而采用 <code>Makefile</code> 来组织代码. <code>Makefile</code> 中放置编译环境中的编译选项, 包括使用 Gecko SDK 编译的路径和配置更新等.</p>
+
+<p>下面是一个使用 SDK 来编译的 <code>Makefile</code>, 这里对 <code>Makefile</code> 的详细用法不做解释. 它与 Visual C++ 的工程(<a href="#Building_a_Microsoft_Visual_Cpp_Project">Building a Microsoft Visual Cpp Project</a>)相类似, 关于 Makefile 的命令请参看 <a class="external" href="http://www.gnu.org/manual/make/">Make 手册</a>.</p>
+
+<p><span id="Gecko_SDK_%E4%B8%8B%E7%9A%84%E4%B8%80%E4%B8%AA_Makefile_%E4%BE%8B%E5%AD%90"><a id="Gecko_SDK_%E4%B8%8B%E7%9A%84%E4%B8%80%E4%B8%AA_Makefile_%E4%BE%8B%E5%AD%90"></a><strong>Gecko SDK 下的一个 Makefile 例子</strong></span></p>
+
+<pre>CXX = c++
+
+CPPFLAGS += -fno-rtti \
+ -fno-exceptions \
+ -shared
+
+# Change this to point at your Gecko SDK directory.
+GECKO_SDK_PATH = /home/dougt/gecko-sdk
+
+# GCC only define which allows us to not have to #include mozilla-config
+# in every .cpp file. If your not using GCC remove this line and add
+# #include "mozilla-config.h" to each of your .cpp files.
+GECKO_CONFIG_INCLUDE = -include mozilla-config.h
+
+GECKO_DEFINES = -DXPCOM_GLUE -DMOZILLA_STRICT_API
+
+GECKO_INCLUDES = -I $(GECKO_SDK_PATH) \
+ -I $(GECKO_SDK_PATH)/xpcom/include \
+ -I $(GECKO_SDK_PATH)/nspr/include \
+ -I $(GECKO_SDK_PATH)/string/include \
+ -I $(GECKO_SDK_PATH)/embedstring/include
+
+GECKO_LDFLAGS = -L $(GECKO_SDK_PATH)/xpcom/bin -lxpcomglue \
+ -L $(GECKO_SDK_PATH)/nspr/bin -lnspr4 \
+ -L $(GECKO_SDK_PATH)/nspr/bin -lplds4 \
+ -L $(GECKO_SDK_PATH)/embedstring/bin/ -lembedstring
+
+build:
+ $(CXX) -o MozShim.so $(GECKO_CONFIG_INCLUDE) $(GECKO_DEFINES) $(GECKO_INCLUDES) $(GECK\
+O_LDFLAGS) $(CPPFLAGS) $(CXXFLAGS) MozShim.cpp
+ chmod +x MozShim.so
+
+clean:
+ rm MozShim.so
+</pre>
+
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/Creating_XPCOM_Components:Packaging_WebLock" style="float: left;">« 上一页</a><a href="/zh-CN/docs/Creating_XPCOM_Components:Resources">下一页 »</a></p>
+</div> <p></p><div class="licenseblock">
+<p>Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the <a class="external" href="http://www.opencontent.org/openpub/" rel="noopener">Open Publication License</a>, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.</p>
+</div><p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/starting_weblock/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/starting_weblock/index.html
new file mode 100644
index 0000000000..65efd53a72
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/starting_weblock/index.html
@@ -0,0 +1,1104 @@
+---
+title: 开始WebLock
+slug: Mozilla/Tech/XPCOM/Guide/Creating_components/Starting_WebLock
+tags:
+ - XPCOM
+ - 所有分类
+translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/Starting_WebLock
+---
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/Creating_XPCOM_Components:Using_XPCOM_Utilities_to_Make_Things_Easier" style="float: left;">« 上一页</a><a href="/zh-CN/docs/Creating_XPCOM_Components:Finishing_the_Component">下一页 »</a></p>
+</div><p></p>
+
+<p>在本章,我们开始设计和实现网络锁定功能本身。我们已经建立了实现多数通用组件功能的模块(例如注册)。这章将关注实际操作网页锁定的功能。</p>
+
+<h3 id="Getting_Called_at_Startup" name="Getting_Called_at_Startup">Getting Called at Startup</h3>
+
+<p>没有人是一个孤岛,组件也一样。你所建立的例子组件到目前为止还没有任何功能。当他被注册以后,他没做任何事情。</p>
+
+<p>为了当某些事件发生的时候被启动或者通知到,例子组件需要挂接到Mozilla,或者覆盖一个现存组件,或者注册到一些事件上面。<strong>WebLock</strong>用后面的方式在Gecko Profile Startup发生的时候被调用。当Gecko应用启动的时候,注册的组件被创建或者通过通用观察者接口被提醒<code>nsIObserver</code>。</p>
+
+<p><em>Observer</em>是一些对象,他们当特定的事件发生的时候被通知。使用这种机制提供了一个相互不必了解而可以在对象之间传送信息的机制。</p>
+
+<p>通常,一个对象会通知一系列观察者。例如一个对象被创建的时候它的<code>observe</code>方法被调用,或者它可以注册当XPCOM关闭的时候被通知。这个接口的核心是<code>observe</code>方法。</p>
+
+<pre>void observe(in nsISupports aSubject,
+ in string aTopic,
+ in wstring aData);
+</pre>
+
+<p>实际上ovserver方法的参数没有什么限制。这些参数根据事件的类型变化。例如,XPCOM关闭的时候,aSubject和aData被定义,aTopic被定义为“xpcom-shotdown’,如果你的对象希望注册到这些事件上面,他首先要实现nsIObserver接口,一旦你完成这些,实现nsIObserverService的observer服务将会利用接口通知你的对象,如下所示:</p>
+
+<p><span id="The_Observer_Interfaces"><a id="The_Observer_Interfaces"></a><strong>The Observer Interfaces</strong></span></p>
+
+<p><img alt="Image:observation-overview.png"></p>
+
+<p>上图表现了observer服务管理了所有<code>nsIObserver</code>对象的列表. 当通知产生的时候,<code>nsIObserverService</code>把呼叫者从<code>NotifyObserver()</code>发送出的消息传送给<code>nsIObserver</code>的<code>Observe()</code>方法。这是一个让不同的类解藕的办法。<code>nsIObserver</code>是一个通用的接口,用来在两个或多个对象间传递信息,而不必定义一个特定的冻结接口,它也是XPCOM建立扩展的一个方式。</p>
+
+<p>WebLock组件对<code>nsIObserver</code>接口的实现和对<code>nsIFactory</code>接口是类似的。<span class="comment">XXX what is Example 2?</span>下面的例子2中,你改变一个类的定义为支持<code>nsIObserver</code>接口并且改变<code>NS_IMPL_ISUPOORTS1</code>,从而<code>QueryInterface</code>实现知道组件也支持<code>nsIObserver</code>。启动的时候被通知的<code>WebLock</code>类定义如下:</p>
+
+<pre>class WebLock: public nsIObserver {
+ public:
+ WebLock();
+ virtual ~WebLock();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIOBSERVER
+};
+
+NS_IMPL_ISUPPORTS1(WebLock, nsIObserver);
+</pre>
+
+<p><code>Observe()</code>最简单的实现仅仅是比较字符串<code>aTopic</code>和对象所接受事件所定义的值. 如果相匹配, 你可以按照你的方式处理事件. 如果对象仅仅注册到一个消息上, 那你可以忽略字符串 <code>aTopic</code> 而仅仅处理事件. 换句话说,对于对象所没有注册的事件,<code>Observe</code> 方法不应该被调用。</p>
+
+<pre>NS_IMETHODIMP
+WebLock::Observe(nsISupports *aSubject,
+ const char *aTopic,
+ const PRUnichar *aData)
+{
+ return NS_OK;
+}
+</pre>
+
+<p>从observer service来的消息可能是间接的. 直接获得来自observer service的消息的方法是初始化一个<code>nsIObserver</code> 对象. 大多数情况下这样是可以的,但是要注意当你通过这个消息建立组件的情况. 因为组件还没有被建立,所以不存在初始化的 <code>nsIObserver</code> 对象可以用来传递给 <code>nsIObserverService</code>, 组件代码在他被装载以前不能做什么.</p>
+
+<h4 id=".E6.B3.A8.E5.86.8C.E5.88.B0.E6.B6.88.E6.81.AF" name=".E6.B3.A8.E5.86.8C.E5.88.B0.E6.B6.88.E6.81.AF">注册到消息</h4>
+
+<p><code>nsIObserverService</code> 接口有处理注册和注销一个<code>nsIObserver</code>对象的方法. 这两个方法用来动态添加或者删除一个notification topic上的observer. 但是 <strong>WebLock</strong> 要被自动初始化和添加到observer service, 这就意味着需要一些数据持久化。(不管怎么说, 我们需要组件在程序每次启动的时候也启动).</p>
+
+<p>This is where a new service that manages sets of related data comes in handy. This service, the <code>nsICategoryService</code>, is what XPCOM and Gecko embedding applications use to persist lists of <code>nsIObserver</code> components that want to have startup notification.</p>
+
+<p>The <code>nsICategoryService</code> maintains sets of name-value pairs like the one below.</p>
+
+<p><span id="The_Category_Manager"><a id="The_Category_Manager"></a><strong>The Category Manager</strong></span></p>
+
+<p><img alt="Image:category-manager-table.png"></p>
+
+<p>Every category is identified by a string that represents the name of the category. Each category contains a set of name-value pairs. For example, you might have a category named "Important People" in which the name-value pairs would be names and phone numbers. The format of the name-value pair is left up to you.</p>
+
+<p>This data structure is more than enough to support the persisting of components that what to be started up. The category name also maps nicely onto the notion of a notification "topic." The topic name could be something like "xpcom-startup", for instance, and the name-value pair could contain the contract IDs required to create the components requesting startup. In fact, this is exactly how categories are used to handle registration with XPCOM for startup notification. You will see the code which does this in the next section.</p>
+
+<h4 id="Getting_Access_to_the_Category_Manager" name="Getting_Access_to_the_Category_Manager">Getting Access to the Category Manager</h4>
+
+<p>Two fields in the <code>nsModuleComponentInfo</code> structure introduced in the last section are addresses for registration and unregistration callbacks. The first callback is called when the component's <code>nsIModule::RegisterSelf</code> method is called. This callback allows the component to execute any one-time registration code it may need. The inverse of this function is the unregistration callback, where it's a good idea to undo whatever the registration function did. The two functions look like this:</p>
+
+<pre>static NS_METHOD
+WebLockRegistration(nsIComponentManager *aCompMgr,
+ nsIFile *aPath,
+ const char *registryLocation,
+ const char *componentType,
+ const nsModuleComponentInfo *info);
+
+static NS_METHOD
+WebLockUnregistration(nsIComponentManager *aCompMgr,
+ nsIFile *aPath,
+ const char *registryLocation,
+ const nsModuleComponentInfo *info);
+</pre>
+
+<p>The names of the functions can be anything you wish. Both functions are passed the Component Manager and the path to the component, including the opaque <code>registryLocation</code>. These are also parameters in the <code>nsIModule</code> implementation in <span class="comment">XXX what is Example 1? link to it here</span>Example 1. In addition to these parameters, the callback functions are passed the <code>nsModuleComponentInfo</code> struct, which is the same structure initially passed into <code>NS_IMPL_NSGETMODULE</code>.</p>
+
+<p>During registration, the registration callback is where you get the <code>nsICategoryManager</code>. Once you have it, you can add the component to the category of components that get started automatically. As a service, the <code>nsICategoryManager</code> is accessible via the <code>nsIServiceManager</code>. Also note that the <code>nsIComponentManager</code> is passed into the callback. Since the object that implements the <code>nsIComponentManager</code> interface also implements <code>nsIServiceManager</code>, all you have to do is <code>QueryInterface</code> the <code>nsIComponentManager</code> to <code>nsIServiceManager</code> to get the Service Manager. You can then use the Service Manager to add the component to the category:</p>
+
+<pre>nsresult rv;
+
+nsCOMPtr&lt;nsIServiceManager&gt; servman =
+ do_QueryInterface((nsISupports*)aCompMgr, &amp;rv);
+
+if (NS_FAILED(rv))
+ return rv;
+</pre>
+
+<div class="side-note">
+<p><span id="%3Ccode%3Edo_QueryInterface%3C/code%3E"><a id="%3Ccode%3Edo_QueryInterface%3C/code%3E"></a><strong><code>do_QueryInterface</code></strong></span></p>
+
+<p>The previous code uses the special <code>nsCOMPtr</code> function <code>do_QueryInterface</code> that lets you <code>QueryInterface</code> without having to worry about reference counting, error handling, and other overhead. The <code>do_QueryInterface</code> knows what interface to <abbr title="QueryInterface">QI</abbr> to based on the <code>nsCOMPtr</code> that is being assigned into. We could have just as easily have used the raw <code>QueryInterface()</code> method, but using <code>nsCOMPtr</code> is much more economical (see <a href="cn/Creating_XPCOM_Components/Using_XPCOM_Utilities_to_Make_Things_Easier#Smart_Pointers">Smart Pointers</a>).</p>
+</div>
+
+<p>Once you have a <code>nsIServiceManager</code> reference, you can ask it for the service you are interested in. This process is similar to using <code>CreateInstance</code> from the <code>nsIComponentManager</code>, but there is no aggregation parameter since the object has already been constructed.</p>
+
+<pre>nsCOMPtr&lt;nsICategoryManager&gt; catman;
+rv = servman-&gt;GetServiceByContractID(NS_CATEGORYMANAGER_CONTRACTID,
+ NS_GET_IID(nsICategoryManager),
+ getter_AddRefs(catman));
+if (NS_FAILED(rv))
+ return rv;
+</pre>
+
+<p>There are two service getters on the <code>nsIServiceManager</code> interface: one that takes a CID and another interface that takes a Contract ID. Here we'll use the latter. The first parameter to the <code>GetServiceByContractID</code> is of course the contract ID, which is defined in the <code>nsXPCOM.h</code> header file. The next parameter is a nifty macro that returns the IID for the interface name that you pass in. The last parameter assigns an out interface pointer to a <code>nsCOMPtr</code>. Assuming there weren't any unexpected errors, the variable <code>catman</code> holds the <code>nsICategoryManager</code> interface pointer, which you can use to add the component as a startup observer by calling a method on the <code>nsICategoryManager</code>.</p>
+
+<p>The next step is to figure out which parameters to pass to the method. There is a category name and a name-value pair, but since the name-value pair meaning is category-specific, you need to figure out which category to use.</p>
+
+<p>There are two startup notifications, both of which create the observer if it isn't already created. The first is provided by XPCOM. This notification will occur during initialization of XPCOM, where all XPCOM services are guaranteed to be available during the calls. Embedding applications may provide other notifications.</p>
+
+<p><span id="Common_XPCOM_Notifications"><a id="Common_XPCOM_Notifications"></a><strong>Common XPCOM Notifications</strong></span></p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">Category</td>
+ <td class="header">Name</td>
+ <td class="header">Value</td>
+ <td class="header">Creates Component</td>
+ </tr>
+ <tr>
+ <td>xpcom-startup</td>
+ <td>Any</td>
+ <td>Contract ID</td>
+ <td>Yes</td>
+ </tr>
+ <tr>
+ <td>xpcom-shutdown</td>
+ <td>Any</td>
+ <td>Contract ID</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>xpcom-autoregistration</td>
+ <td>Any</td>
+ <td>Contract ID</td>
+ <td>No</td>
+ </tr>
+ <tr>
+ <td>app-startup</td>
+ <td>Any</td>
+ <td>service, Contract ID</td>
+ <td>*</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>The table above summarizes the popular persistent notifications registered through the category manager. The name of the category itself is a well defined string, but the name-value pairs can be anything.</p>
+
+<p>When naming your component in the category, take care to use something that means something and doesn't muddy up the namespace. In this case, "WebLock" is unique and provides context to anyone looking at the category. The value of the name-value part is expected to be the contract ID of the component.</p>
+
+<p>Since every category can define the name-value pairs, the application "app-startup" category can support not only services but component instances as well. For the app-startup notification, you must explicitly pass the string "service," prior to the component's Contract ID. If you do not, the component will be created and then released after the notification, which may cause the component to be deleted.</p>
+
+<p>In short, to register the <strong>WebLock</strong> component as an xpcom-startup observer, do the following:</p>
+
+<pre>char* previous = nsnull;
+rv = catman-&gt;AddCategoryEntry("xpcom-startup",
+ "WebLock",
+ WebLock_ContractID,
+ PR_TRUE, // persist category
+ PR_TRUE, // replace existing
+ &amp;previous);
+if (previous)
+ nsMemory::Free(previous); // free the memory the replaced value might have used
+</pre>
+
+<p>The unregistration, which should occur in the unregistration callback, looks like this:</p>
+
+<pre>rv = catman-&gt;DeleteCategoryEntry("xpcom-startup",
+ "WebLock",
+ PR_TRUE); // persist
+</pre>
+
+<p>A complete code listing for registering <strong>WebLock</strong> as a startup observer follows:</p>
+
+<pre>#define MOZILLA_STRICT_API
+
+#include "nsIGenericFactory.h"
+
+#include "nsCOMPtr.h"
+#include "nsXPCOM.h"
+#include "nsIServiceManager.h"
+#include "nsICategoryManager.h"
+
+#include "nsMemory.h"
+
+#include "nsIObserver.h"
+
+#include "nsEmbedString.h"
+
+#define WebLock_CID \
+{ 0x777f7150, 0x4a2b, 0x4301, \
+{ 0xad, 0x10, 0x5e, 0xab, 0x25, 0xb3, 0x22, 0xaa}}
+
+#define WebLock_ContractID "@dougt/weblock"
+
+class WebLock: public nsIObserver
+{
+ public:
+ WebLock();
+ virtual ~WebLock();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIOBSERVER
+};
+
+WebLock::WebLock()
+{
+ NS_INIT_ISUPPORTS();
+}
+
+WebLock::~WebLock()
+{
+}
+
+NS_IMPL_ISUPPORTS1(WebLock, nsIObserver);
+
+NS_IMETHODIMP
+WebLock::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *aData)
+{
+ return NS_OK;
+}
+
+static NS_METHOD WebLockRegistration(nsIComponentManager *aCompMgr,
+ nsIFile *aPath,
+ const char *registryLocation,
+ const char *componentType,
+ const nsModuleComponentInfo *info)
+{
+ nsresult rv;
+
+ nsCOMPtr&lt;nsIServiceManager&gt; servman = do_QueryInterface((nsISupports*)aCompMgr, &amp;rv);
+ if (NS_FAILED(rv))
+ return rv;
+
+ nsCOMPtr&lt;nsICategoryManager&gt; catman;
+ rv = servman-&gt;GetServiceByContractID(NS_CATEGORYMANAGER_CONTRACTID,
+ NS_GET_IID(nsICategoryManager),
+ getter_AddRefs(catman));
+
+ if (NS_FAILED(rv))
+ return rv;
+
+ char* previous = nsnull;
+ rv = catman-&gt;AddCategoryEntry("xpcom-startup",
+ "WebLock",
+ WebLock_ContractID,
+ PR_TRUE,
+ PR_TRUE,
+ &amp;previous);
+ if (previous)
+ nsMemory::Free(previous);
+
+ return rv;
+}
+
+static NS_METHOD WebLockUnregistration(nsIComponentManager *aCompMgr,
+ nsIFile *aPath,
+ const char *registryLocation,
+ const nsModuleComponentInfo *info)
+{
+ nsresult rv;
+
+ nsCOMPtr&lt;nsIServiceManager&gt; servman = do_QueryInterface((nsISupports*)aCompMgr, &amp;rv);
+ if (NS_FAILED(rv))
+ return rv;
+
+ nsCOMPtr&lt;nsICategoryManager&gt; catman;
+ rv = servman-&gt;GetServiceByContractID(NS_CATEGORYMANAGER_CONTRACTID,
+ NS_GET_IID(nsICategoryManager),
+ getter_AddRefs(catman));
+ if (NS_FAILED(rv))
+ return rv;
+
+ rv = catman-&gt;DeleteCategoryEntry("xpcom-startup",
+ "WebLock",
+ PR_TRUE);
+
+ return rv;
+}
+
+NS_GENERIC_FACTORY_CONSTRUCTOR(WebLock)
+
+static const nsModuleComponentInfo components[] =
+{
+ {
+ "WebLock",
+ WebLock_CID,
+ WebLock_ContractID,
+ WebLockConstructor,
+ WebLockRegistration,
+ WebLockUnregistration
+ }
+};
+
+NS_IMPL_NSGETMODULE(WebLockModule, components)
+</pre>
+
+<h3 id="Providing_Access_to_WebLock" name="Providing_Access_to_WebLock">Providing Access to <strong>WebLock</strong></h3>
+
+<p>At this point, the component will be called when XPCOM starts up. <strong>WebLock</strong> has already implemented the <code>nsISupports</code>, <code>nsIFactory</code>, <code>nsIModule</code>, and <code>nsIObserver</code> interfaces that handle generic component functionality including being initialized at startup. And it speaks to the Component Manager, Service Manager, Category Manager, and the Component Registrar to register itself properly with XPCOM.</p>
+
+<p>The next step is to expose additional functionality to Gecko applications and other clients to query and control the <strong>WebLock</strong> component. For example, the user interface needs to be able to enable and disable the web locking functionality, see what sites are in the whitelist, and add or remove sites from that list. WebLock needs to provide an API, and it needs to hook into Gecko in order to implement the actual locking functionality.</p>
+
+<p>译: 下一步是expose另外的功能以使得Gecko应用以及其它clients查询和控制WebLock组件. 例如, user interface(用户接口)要有能力去允许或者禁止web locking(web锁定)功能, 查看哪些站点在白名单列表中, 并向列表中添加或移除站点. WebLock需要提供一个API并挂接到Gecko中进而实现实际的locking功能.</p>
+
+<div class="side-note">
+<p><span id="The_WebLock_User_Interface"><a id="The_WebLock_User_Interface"></a><strong>The WebLock User Interface</strong></span></p>
+
+<p>The <strong>WebLock</strong> component in this tutorial uses XUL to define the additional browser UI in a cross-platform way, and XUL uses JavaScript to access and control XPCOM components, but Gecko's pluggable UI allows any user interface to call into Gecko and the components you create as easily as you can from XUL. See <a href="cn/Creating_XPCOM_Components/Building_the_WebLock_UI#XUL">XUL</a> for a discussion of how XUL interacts with JavaScript and XPCOM.</p>
+
+<p>在这个教程中<strong>WebLock</strong>组件使用XUL来定义跨平台的浏览器UI, XUL使用JavaScript来访问和控制XPCOM组件, 但Gecko的可挂接UI也允许任何user interface调用Gecko和你所创建的组件, 就如同XUL一样容易. <a href="cn/Creating_XPCOM_Components/Building_the_WebLock_UI#XUL">XUL</a>讨论了XUL如何与JavaScript和XPCOM交互.</p>
+</div>
+
+<h3 id="Creating_the_WebLock_Programming_Interface" name="Creating_the_WebLock_Programming_Interface">Creating the WebLock Programming Interface</h3>
+
+<p>Design is one of the hardest parts of any programming problem. The question the interface for the <strong>WebLock</strong> component must answer is: How should <strong>WebLock</strong> look to the outside world? What, in other words, is the interaction of clients with the <strong>WebLock</strong> component? In this section, we enumerate the basic functionality the component should expose and create the single interface that organizes and provides this functionality.</p>
+
+<p>译: 设计是任何编程问题中最困难的部分之一. 问题是<strong>WebLock</strong>组件必须要回答一些问题: <strong>WebLock</strong>应该如何look to外面的世界? 换言之, 什么是clients与<strong>WebLock</strong>的交互? 在这部分列举了组件应该expose的基本功能和create一个组织和提供这些功能的接口.</p>
+
+<p>Instead of starting with the implementation, developers use XPIDL (see <a href="cn/Creating_XPCOM_Components/An_Overview_of_XPCOM#XPIDL_and_Type_Libraries">XPIDL and Type Libraries</a> for more information about XPIDL) to define the interface to the component: how the functionality should be organized, expressed, and exposed to its clients.</p>
+
+<p>译: 开发人员应该使用XPIDL(see <a href="cn/Creating_XPCOM_Components/An_Overview_of_XPCOM#XPIDL_and_Type_Libraries">XPIDL and Type Libraries</a> for more information about XPIDL)为组件定义接口(定义功能应该如何被组织, 描述和暴露给它的clients)做为开始, 而不应该从实现开始.</p>
+
+<p>In general, the <strong>WebLock</strong> service interface needs to include the following functionality:</p>
+
+<p>译: 通常, <strong>WebLock</strong>服务接口要包括以下功能:</p>
+
+<ul>
+ <li><code>Lock</code> - Enable web locking so that any browser in the Gecko application is restricted to the white list of website domains.</li>
+</ul>
+
+<p>        译: <code>Lock</code> - 允许web locking, 这样任何Gecko应用中的浏览器被限定只能访问白名单中的web站点域.</p>
+
+<ul>
+ <li><code>Unlock</code> - Disable web locking. This should allow any browser in the Gecko application to browse any website regardless of the white list.</li>
+</ul>
+
+<p>        译: <code>Unlock</code> - 禁止web locking. 允许Gecko应该中的浏览器访问任何web站点, 而不去管白名单列表.</p>
+
+<ul>
+ <li><code>AddSite</code> - Add the current URL to the white list.</li>
+</ul>
+
+<p>        译: <code>AddSite</code> - 添加当前URL到白名单列表.</p>
+
+<ul>
+ <li><code>RemoveSite</code> - Remove the current URL from the white list.</li>
+</ul>
+
+<p>        译: <code>RemoveSite</code> - 从白名单列表中移除当前URL.</p>
+
+<ul>
+ <li><code>EnumerateSites</code> - Allows the enumeration of all sites in the white list. <code>EnumerateSites</code> might be used in the user interface to provide something like an editable listbox of all sites in the white list.</li>
+</ul>
+
+<p>        译: <code>EnumerateSites</code> - 允许列举出所有白名单中的站点. <code>EnumerateSites</code>可能会被user         interface(用户接口/用户界面)所提供的例如显示所有白名单列表的可编辑列表框控件所使用.</p>
+
+<p>Even this simple outline presents some ambiguity, however. It's certainly not enough to spell out the interface for the <strong>WebLock</strong> component in this way. For example, <code>AddSite</code> is supposed to add the current URL to the white list, but is the URL an input parameter to the method, is it the topmost web page in the Gecko application, or is it something more random-a URL picked from global history or that's been given context in some other way?</p>
+
+<p>As a strongly typed and implementation-agnostic language, XPIDL requires that you be quite specific about the APIs, the list of parameters, their order, and their types. XPIDL requires that you spell it all out, in other words. And it's this formality that makes the interfaces in XPCOM effective contracts between services and clients.</p>
+
+<p>The next section shows the interface of the <strong>WebLock</strong> component, <code>iWebLock</code>, in XPIDL. Once the interface has been described in the XPIDL language, the interface file can be used to generate the header files needed for the implementation code, the binary type library files that let you use the interface of the <strong>WebLock</strong> component from JavaScript, and even <span class="comment">broken link</span><a href="cn/Javadoc">javadoc</a> style HTML documentation.</p>
+
+<h3 id="Defining_the_Weblock_Interface_in_XPIDL" name="Defining_the_Weblock_Interface_in_XPIDL">Defining the <strong>Weblock</strong> Interface in XPIDL</h3>
+
+<p>Most interfaces in the XPCOM world are described in XPIDL. The XPIDL file for the <code>iWebLock</code> interface can be used to generate the C++ header file, which you'll need to implement the interface in the component and also a type library that makes the component accessible from JavaScript or other interpreted languages. In Mozilla, JavaScript is the bridge between components and the XUL-based user interface.</p>
+
+<p>译: 在XPCOM世界里大多数接口都是用XPIDL描述的. <code>iWebLock</code>接口的XPIDL文件可以被用来生成C++ header file(你需要它来在组件中实现接口和用来使组件在JavaScript和其它的解译型语言中可访问的类型库). 在Mozilla中, JavaScript是组件与基于XUL的user interface之间的桥梁.</p>
+
+<p>The XPIDL Syntax (XPIDL语法)</p>
+
+<p>The XPIDL syntax is a mix of C++ and Java, and of course it's very much like the OMG IDL upon which it is closely based. The XPIDL for <code>iWebLock</code> appears below:</p>
+
+<p><span id="iWebLock"><a id="iWebLock"></a><strong>iWebLock</strong></span></p>
+
+<pre>#include "nsISupports.idl"
+interface nsISimpleEnumerator;
+[scriptable, uuid(ea54eee4-9548-4b63-b94d-c519ffc91d09)]
+interface iWeblock : nsISupports
+{
+ void lock();
+ void unlock();
+
+ // assume strings are UTF-8
+ void addSite(in string url);
+ void removeSite(in string url);
+ attribute nsISimpleEnumerator sites;
+};
+</pre>
+
+<p>The first line includes the file <code>nsISupports.idl</code>, which defines the <code>nsISupports</code> interface from which all XPCOM interfaces must derive, and makes it possible for the <code>iWebLock</code> interface to subclass that base interface.</p>
+
+<pre>#include "nsISupports.idl"
+</pre>
+
+<p>The next line of the XPIDL is a forward declaration of the interface <code>nsISimpleEnumerator</code>. Again, this is similar to the forward declare in C++ (except that C++ does not have the <code>interface</code> keyword seen here).</p>
+
+<pre>interface nsISimpleEnumerator;
+</pre>
+
+<p>See the <a href="cn/Creating_XPCOM_Components/Resources#XPCOM_Resources">XPCOM resources</a> for more information about the XPIDL syntax.</p>
+
+<h4 id="Scriptable_Interfaces" name="Scriptable_Interfaces">Scriptable Interfaces</h4>
+
+<p>The third line in <a href="#iWebLock">iWebLock</a> is more complex. The first thing it says is that <code>iWebLock</code> will be<em>scriptable</em> .</p>
+
+<pre>[scriptable, uuid(ea54eee4-9548-4b63-b94d-c519ffc91d09)]
+</pre>
+
+<p>The rest of the line provides a UUID for this interface. Recall that every interface has a unique number that is assigned to it. In the case of interfaces, the identifier is an IID. In the case of the components, which also require unique identifiers, the identifier is the CID.</p>
+
+<h4 id="Subclassing_nsISupports" name="Subclassing_nsISupports">Subclassing <code>nsISupports</code></h4>
+
+<p>The next line in <a href="#iWebLock">iWebLock</a> names the interface and defines its base interface. <code>iWeblock</code> derives from <code>nsISupports</code>. XPIDL has no way to define multiple inheritance - something that all scriptable objects must deal with.</p>
+
+<pre>interface iWebLock : nsISupports
+</pre>
+
+<h4 id="The_Web_Locking_Interface" name="The_Web_Locking_Interface">The Web Locking Interface</h4>
+
+<p>The body of the block (the stuff between the curly braces) defines the methods and attributes of our interface. There are basically two functional sets on this interface. The first section of the interface controls whether or not <strong>WebLock</strong> checks to see if a web page can be loaded. If locked, <strong>WebLock</strong> will prevent sites not on the white list from loading.</p>
+
+<pre> void lock();
+ void unlock();
+</pre>
+
+<p>This interface does not enforce any policy with respect to how the user enables or disables this feature. This allows maximum flexibility in the implementation. Any place in the application can acquire this interface via the Service Manager and call <code>unlock</code> or <code>lock</code>. For example, the user interface may bring up a dialog asking the user for a password before calling <code>unlock</code>. Another area of code, such as a "Profile Manager" that starts up and lets users choose which profile to use, may unconditionally call <code>unlock</code> on such a component when switching a profile.</p>
+
+<p>The next set of functionality manages the white list where acceptable domains are stored:</p>
+
+<pre> void addSite(in string url);
+ void removeSite(in string url);
+ attribute nsISimpleEnumerator sites;
+</pre>
+
+<p>Operations in this set - <code>add</code>, <code>remove</code>, and <code>enumerate</code> - will be called from a user interface that manages the white list and adds the current website to the white list. There is no policy applied to what sites get added or removed to this list, or who can remove a site.</p>
+
+<p>The most interesting method definition is the enumerator. First of all, it does not look like a method at all:</p>
+
+<pre>attribute nsISimpleEnumerator sites;
+</pre>
+
+<p>This line defines an attribute in the interface. In C++, this is considered a public variable and "compiled" into a <code>Get</code> method (e.g., <code>getSites</code>). If an attribute is not marked <code>readonly</code>, then both <code>Get</code> and <code>Set</code> methods are generated.</p>
+
+<p>The getter created by this attribute returns a <code>nsISimpleEnumerator</code> interface pointer. This interface allows you to pass a list of elements between interfaces. It has two methods: <code>hasMoreElements()</code> and <code>getNext()</code>.</p>
+
+<pre>[scriptable, uuid(D1899240-F9D2-11D2-BDD6-000064657374)]
+interface nsISimpleEnumerator : nsISupports
+{
+ /**
+ * Called to determine whether or not the enumerator has
+ * any elements that can be returned via getNext(). This method
+ * is generally used to determine whether or not to initiate or
+ * continue iteration over the enumerator, though it can be
+ * called without subsequent getNext() calls. Does not affect
+ * internal state of enumerator.
+ *
+ * @see getNext()
+ * @return PR_TRUE if there are remaining elements in the enumerator.
+ * PR_FALSE if there are no more elements in the enumerator.
+ */
+ boolean hasMoreElements();
+
+ /**
+ * Called to retrieve the next element in the enumerator. The "next"
+ * element is the first element upon the first call. Must be
+ * preceded by a call to hasMoreElements() which returns PR_TRUE.
+ * This method is generally called within a loop to iterate over
+ * the elements in the enumerator.
+ *
+ * @see hasMoreElements()
+ * @return NS_OK if the call succeeded in returning a non-null
+ * value through the out parameter.
+ * NS_ERROR_FAILURE if there are no more elements
+ * to enumerate.
+ * @return the next element in the enumeration.
+ */
+ nsISupports getNext();
+};
+</pre>
+
+<h3 id="Implementing_WebLock" name="Implementing_WebLock">Implementing <strong>WebLock</strong></h3>
+
+<p>Once you have defined the interfaces that the component will implement, you can begin to write the implementation code that will actually carry out the web locking functionality.</p>
+
+<p>The <strong>WebLock</strong> component implements three interfaces:</p>
+
+<ul>
+ <li><code>nsISupports</code></li>
+ <li><code>nsIObserver</code></li>
+ <li><code>iWebLock</code></li>
+</ul>
+
+<p><code>nsISupports</code> is the base interface that all XPCOM objects must implement. The <code>nsIObserver</code> interface is for listening to various events that Gecko generates. Finally, the <code>iWebLock</code> interface is the interface that actually controls the web locking functionality. The first two have already been implemented as part of the generic module code. Recall from <a href="cn/Creating_XPCOM_Components/Using_XPCOM_Utilities_to_Make_Things_Easier">Using XPCOM Utilities to Make Things Easier</a> that implementing these basic interfaces can be easy and straightforward if you use the macros and other utilities that XPCOM provides.</p>
+
+<h4 id="Declaration_Macros" name="Declaration_Macros">Declaration Macros</h4>
+
+<p>The class declaration for the <code>WebLock</code> class that implements these three interfaces is as follows:</p>
+
+<pre>class WebLock: public nsIObserver, public iWebLock
+{
+ public:
+ WebLock();
+ virtual ~WebLock();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIOBSERVER
+ NS_DECL_IWEBLOCK
+};
+</pre>
+
+<p>Note that we derive from the <code>nsIObserver</code> interface as well as the <code>iWeblock</code> class. We do not need to explicitly derive from <code>nsISupports</code> as both of these two other interfaces are already subclasses of <code>nsISupports</code>:</p>
+
+<p><span id="Interface_Hierarchy_for_WebLock"><a id="Interface_Hierarchy_for_WebLock"></a><strong>Interface Hierarchy for WebLock</strong></span></p>
+
+<p><img alt="Image:weblock-interface-hierarchy.png"></p>
+
+<p>The body of the class declaration uses declaration macros that are generated from an XPIDL interface file. Every header generated from an XPIDL file has a similar macro that defines all the methods in that interface. This makes changes to the interface when designing a bit simpler, as you do not have to modify any class declarations.</p>
+
+<p>There are times, of course, when you cannot use these macros-as when two interfaces share the same method signatures. In these cases you have to manually declare the methods in your class. But in practice, manually declaring class methods in XPCOM is the exception and not the rule. The <code>NS_DECL_IWEBLOCK</code> declaration macro expands into the following:</p>
+
+<pre> NS_IMETHOD Lock(void);
+ NS_IMETHOD Unlock(void);
+ NS_IMETHOD AddSite(const char *url);
+ NS_IMETHOD RemoveSite(const char *url);
+ NS_IMETHOD GetSites(nsISimpleEnumerator * *aSites);
+ NS_IMETHOD SetSites(nsISimpleEnumerator *aSites);
+</pre>
+
+<h4 id="Representing_Return_Values_in_XPCOM" name="Representing_Return_Values_in_XPCOM">Representing Return Values in XPCOM</h4>
+
+<p>The code sample above is the C++ version of the <code>iWebLock</code> interface methods. The return result of XPCOM methods generated from XPIDL is always of the type <code>nsresult</code>, and the small macro used in these expansions, <code>NS_IMETHOD</code>, actually represents that return type. <code>nsresult</code> is returned even when in XPIDL you specify that the method return a <code>void</code>. If you require the return result to be something else, the methods are not truly XPCOM methods. If you really want to change the return result type you can use a special flag in your XPIDL that denotes this (see <a class="external" href="http://www.mozilla.org/scriptable/xpidl/">the XPIDL reference</a>). However, we suggest that you simply add an out parameter to the method.</p>
+
+<h4 id="XPIDL_Code_Generation" name="XPIDL_Code_Generation">XPIDL Code Generation</h4>
+
+<p>The XPIDL compiler also generates a stub implementation of the interface in a commented section of the generated header file, in which each method returns <code>NS_ERROR_NOT_IMPLEMENTED</code>. If you copy the stub implementation from the header file into the source, then rename the dummy class name ("<code>_MYCLASS_</code>") to the <code>WebLock</code> class name already defined, you should be able to compile the source successfully.</p>
+
+<h4 id="Getting_the_WebLock_Service_from_a_Client" name="Getting_the_WebLock_Service_from_a_Client">Getting the WebLock Service from a Client</h4>
+
+<p>At this point, you can install the XPCOM component and have other systems use it. The component doesn't do anything useful, of course, but you have written enough of the code to have it recognized and accessed as a component in XPCOM. The code snippet below illustrates how to get the <strong>WebLock</strong> service when the component is present:</p>
+
+<pre>nsCOMPtr&lt;nsIServiceManager&gt; servMan;
+nsresult rv = NS_GetServiceManager(getter_AddRefs(servMan));
+if (NS_FAILED(rv))
+{
+ printf("ERROR: XPCOM error [%x].\n", rv);
+ return -1;
+}
+nsCOMPtr&lt;iWebLock&gt; weblock;
+rv = servMan-&gt;GetServiceByContractID("@dougt/weblock",
+ NS_GET_IID(iWeblock),
+ getter_AddRefs(weblock));
+
+if (NS_FAILED(rv))
+{
+ printf("ERROR: XPCOM obtaining service [%x].\n", rv);
+ return -1;
+}
+</pre>
+
+<h4 id="Implementing_the_iWebLock_Interface_.28.E5.AE.9E.E7.8E.B0iWebLock.E6.8E.A5.E5.8F.A3.29" name="Implementing_the_iWebLock_Interface_.28.E5.AE.9E.E7.8E.B0iWebLock.E6.8E.A5.E5.8F.A3.29">Implementing the <code>iWebLock</code> Interface (实现iWebLock接口)</h4>
+
+<p>Once the interface is defined, you can focus on implementing the web lock startup functionality itself. The <strong>WebLock</strong> component starts automatically when XPCOM is started up because it's been registered as a category in XPCOM. When <strong>WebLock</strong> is called, one of the first things it wants to do is read in a file that lists the <abbr title="Uniform Resource Locator">URLs</abbr> that the browser is allowed to load. This file can exist anywhere on the local system, but we've placed it next to the application to keep things simple. The first step in this implementation phase, then, is to create the functionality that accesses this <strong>WebLock</strong> white list and uses its data to determine which domains are allowed and which are to be blocked. For this, we need to use the file interfaces available in XPCOM.</p>
+
+<p>一旦接口已被定义, 那你的重点应该放在实现web lock的功能上. 当XPCOM运行后WebLock组件也会被自动运行, 因为它已经被注册成为一个XPCOM中的category. 当WebLock被调用时, 它应该做的第一个事情就是读取一个文件, 这个文件列出了允许被浏览器加载的URLs. 这个文件可以位于本地系统中的任何位置, 但我们需要将其放置在距应用程序不远的地方以便操作起来简单一些. 接下来在实现阶段的第一步是实现两个功能, 一是访问WebLock的白名单, 二是使用这些数据去决定哪些域是被允许, 以及哪些是应该被拦截的. 为此, 我们需要使用XPCOM中的文件接口.</p>
+
+<h5 id="File_Interfaces" name="File_Interfaces">File Interfaces</h5>
+
+<p>Files and directories are abstracted and encapsulated by interfaces. There are a few reasons for not using strings to represent file locations, but the most important one is that not all file systems can be represented by a series of characters separated by a slash. On the Macintosh platform, for example, files are represented as a triplet - two numbers and one string - so using a string on the Macintosh does not adequately identify files on that operating system.</p>
+
+<p>文件和目录是通过接口来抽象和封装的. 这里有几个原因说明为什么不使用字符串来表示文件位置, 但更重要的一点是并不是所有的文件系统都能够表示成斜线所分割的字符序列. 例如, 在Macintosh(Apple的系统)平台上, 文件被表示成一个triplet(意思是由三个部分组成), 两个数字一个字符串, 因此在Macintosh系统上使用字符串并不能充分在标识文件.</p>
+
+<p><code>nsIFile</code>, the file interface in XPCOM, provides most of the functionally that file handling requires. That interface includes members representing the file name, file attributes, permissions, existence, and others. A related interface called <code>nsILocalFile</code> provides access to operations specific to local files, but the <code>nsIFile</code> functionality is adequate for the <strong>WebLock</strong> component.</p>
+
+<p>nsIFile, XPCOM中的文件接口, 提供了大多数操作文件所必须的功能. 这个接口中所包含的成员描述了文件的名字, 属性, 权限, 是否存在等等. 与之相关的接口nsILocalFile提供 操作特定的本地文件, 不过nsIFile的功能对于WebLock组件来说已经足够了.</p>
+
+<p><span id="File_Interface_Hierarchy"><a id="File_Interface_Hierarchy"></a><strong>File Interface Hierarchy</strong></span></p>
+
+<p><img alt="Image:file-iface-hierarchy.png"></p>
+
+<div class="side-note">
+<p><span id="Remote_Files_and_nsIFile"><a id="Remote_Files_and_nsIFile"></a><strong>Remote Files and nsIFile</strong></span></p>
+
+<p>It is not inconceivable for remote files to be represented by the <code>nsIFile</code> interface. Someone could write an <code>nsIFile</code> implementation that represented FTP files on some server. The existing code would need to change very little for a <strong>WebLock</strong> implementation to take advantage of files that do not actually exist on disk. This kind of implementation does not exist, but this expandability shows some of the flexibility that interface-based programming can provide.</p>
+
+<p>并不难想象, 为远程文件使用nsIFile接口来表示它. 某人可以写一个nsIFile的实现用以表示一些服务器上的FTP文件. 已经存在的代码必须要做一些效小的修改以使WebLock的实现可以接受实际上并不是存在于磁盘上的文件. 这种类型的实现虽然还并不存在, 但至少这种扩展性可以显现出一些基于接口的编程带来的灵活性.</p>
+
+<p>The <a href="cn/XPCOM_API_Reference">XPCOM API Reference</a> contains detailed information on <code>nsIFile</code> and other XPCOM interfaces.</p>
+</div>
+
+<h4 id="The_Directory_Service_.28.E7.9B.AE.E5.BD.95.E6.9C.8D.E5.8A.A1.29" name="The_Directory_Service_.28.E7.9B.AE.E5.BD.95.E6.9C.8D.E5.8A.A1.29">The Directory Service (目录服务)</h4>
+
+<p>The file interfaces are most useful when you can use them to find and manipulate files that are relative to the application. The Directory Service provides directory and file locations in a cross platform uniform way to make this easier. This service, available as <code>nsIDirectoryService</code>, stores the location of various common system locations, such as the the directory containing the running process, the user's <code>HOME</code> directory, and others. It can be expanded so that applications and components can define and store their own special locations - an application plugin directory, for example, preference files and/or directories, or other application specific paths. For example, to expose the location of the "white list" file containing all of the URLs that are safe for <strong>WebLock</strong>, you can add its location to the <code>nsDirectoryService</code>, which clients can then query for this infomation.</p>
+
+<p>文件接口较有助于当你使用它们去查找和操作与应用相关的文件. 目录服务提供了跨平台的目录与文件定位的统一方法, 这使得进行这种操作变得容易. 这个服务(利用nsIDirectoryService)存储了各种各样通用系统区域的位置, 例如像是包括了正在运行的程序的目录, 用户的HOME目录等等. 因此它可以被扩展为应用程序和组件能够定义并且存储它们自己的特定位置(应用程序插件目录), 例如, 用户自定义的文件和目录, 或者其它的应用程序的特定路径. 比如指定一个"white list"所在的位置, 它包括了所有对于WebLock来讲是安全的URLs, 你可以将这个位置添加到nsDirectoryService中, 使客户端接下来可以查询到这个信息.</p>
+
+<p>The Directory Service implements the <code>nsIProperties</code> interface, which allows you to <code>Get()</code>, <code>Set()</code>, and <code>Undefine()</code> interface pointers. In the case of <strong>WebLock</strong>, these interface pointers will be <code>nsIFile</code> objects.</p>
+
+<p>目录服务实现了nsIProperties接口, 它允许你Get(), Set()以及Undefine()接口指针. 在WebLock中这些接口指针是nsIFile对象.</p>
+
+<pre>[scriptable, uuid(78650582-4e93-4b60-8e85-26ebd3eb14ca)]
+interface nsIProperties : nsISupports
+{
+ /**
+ * Gets a property with a given name.
+ * 用给定的名字(name)取得一个属性(property)
+ *
+ * @return NS_ERROR_FAILURE if a property with that
+ * name doesn't exist.
+ * 如果给定名字的属性不存在, 函数返回NS_ERROR_FAILURE
+ * @return NS_ERROR_NO_INTERFACE if the
+ * found property fails to QI to the
+ * given iid.
+ * 如果取得的属性在以给定的iid于QI方法上调用失败,
+ * 函数返回NS_ERROR_NO_INTERFACE
+ */
+ void get(in string prop,
+ in nsIIDRef iid,
+ [iid_is(iid),retval] out nsQIResult result);
+
+ /**
+ * Sets a property with a given name to a given value.
+ * 用给定的名字和给定的值为设置一个属性
+ */
+ void set(in string prop, in nsISupports value);
+
+ /**
+ * Returns true if the property with the given name exists.
+ * 如果与给定名字的属性存在, 返回true
+ */
+ boolean has(in string prop);
+
+ /**
+ * Undefines a property. 取消一个属性的定义
+ * @return NS_ERROR_FAILURE if a property with that name doesn't
+ * already exist.
+ * 如果给定名字的属性还不存在, 那么函数返回NS_ERROR_FAILURE
+ */
+ void undefine(in string prop);
+
+ /**
+ * Returns an array of the keys.
+ * 返回一个key的集合
+ */
+ void getKeys(out PRUint32 count,
+ [array, size_is(count), retval] out string keys);
+};
+</pre>
+
+<p><span id="Directory_Service_Hierarchy"><a id="Directory_Service_Hierarchy"></a><strong>Directory Service Hierarchy</strong></span></p>
+
+<p><img alt="Image:directoryservice-iface-hierarchy.png"></p>
+
+<p>There are two steps involved to find directories or files with the Directory Service (<code>nsIDirectoryService</code>). You must know the string key (or property) that refers to the location you are interested in, which is published in the file <code>nsDirectoryServiceDefs.h</code> that comes with the Gecko SDK (for a listing of these locations, see the <a href="cn/XPCOM_API_Reference">XPCOM API Reference</a>). The string key for the directory containing the application executable is <code>NS_XPCOM_CURRENT_PROCESS_DIR</code>. Given this key, you can acquire the directory service, call <code>Get()</code>, and pass the key. In the example below, <code>appDir</code> will point to the directory that contains the executable.</p>
+
+<p>这里有两个步骤有关于通过目录服务(nsIDirectoryService)查找目录或文件. 你必须要知道字符串键(或叫属性)用以引用你所想要的位置, 字符串键(或叫属性)被公开于随Gecko SDK一起提供的nsDirectoryServiceDefs.h文件中(可参见<a href="cn/XPCOM_API_Reference">XPCOM API Reference</a>以得到这些位置的一个列表). 包含可执行程序的目录的字符串键是NS_XPCOM_CURRENT_PROCESS_DIR. 给定这个键, 你就可以通过调用Get()并将键传递到函数中以获得目录服务. 在下面的实例中, appDir将指向一个包含了可执行程序的目录.</p>
+
+<pre>nsCOMPtr&lt;nsIServiceManager&gt; servMan;
+nsresult rv = NS_GetServiceManager(getter_AddRefs(servMan));
+if (NS_FAILED(rv)) return -1;
+
+nsCOMPtr&lt;nsIProperties&gt; directoryService;
+rv = servMan-&gt;GetServiceByContractID(NS_DIRECTORY_SERVICE_CONTRACTID,
+ NS_GET_IID(nsIProperties),
+ getter_AddRefs(directoryService));
+
+if (NS_FAILED(rv)) return -1;
+
+nsCOMPtr&lt;nsIFile&gt; appDir;
+rv = directoryService-&gt;Get(NS_XPCOM_CURRENT_PROCESS_DIR,
+ NS_GET_IID(nsIFile),
+ getter_AddRefs(appDir));
+
+if (NS_FAILED(rv)) return -1;
+</pre>
+
+<p>Most of the useful functionality is exposed by the <code>nsIProperties</code> interface, but the directory service also implements <code>nsIDirectoryService</code>. This interface allows you to extend and override <code>nsIFile</code> objects registered with the directory service. There are currently two ways to add a file location to the directory service: directly and using the delayed method. The direct method is to add a new <code>nsIFile</code> object using the <code>nsIProperties</code> interface, in which case you pass the <code>nsIFile</code> object as an <code>nsISupports</code> to the <code>Set()</code> method of the <code>nsIProperties</code> interface.</p>
+
+<p>大多数有用的功能都是通过nsIProperties接口所提供, 但目录服务还实现了nsIDirectoryService. nsIDirectoryService接口允许利用目录服务你去扩展和重写nsIFile对象的注册. 当前有两种方法添加一个文件位置到目录服务中:立即的与延迟的两种方法. 立即的方法是使用nsIProperties接口添加一个新的nsIFile对象, 在这种情况下你要把nsIFile对象当成一个nsISupports传递给nsIProperties接口的Set()函数.</p>
+
+<p>In the delayed method, you register to be a callback that can provide an <code>nsIFile</code>. To do this, you must get the implementation like we did above. When you have it, <code>QueryInterface</code> for the <code>nsIDirectoryService</code> interface. In this interface, there is a function which allows you to register an <code>nsIDirectoryServiceProvider</code> interface. The interface callback looks like this:</p>
+
+<pre>[scriptable, uuid(bbf8cab0-d43a-11d3-8cc2-00609792278c)]
+interface nsIDirectoryServiceProvider: nsISupports
+{
+/**
+* getFile
+*
+* Directory Service calls this when it gets the first request for
+* a prop or on every request if the prop is not persistent.
+*
+* @param prop The symbolic name of the file.
+* @param persistent TRUE - The returned file will be cached by Directory
+* Service. Subsequent requests for this prop will
+* bypass the provider and use the cache.
+* FALSE - The provider will be asked for this prop
+* each time it is requested.
+*
+* @return The file represented by the property.
+*
+*/
+nsIFile getFile(in string prop, out PRBool persistent);
+};
+</pre>
+
+<h4 id="Modifying_Paths_with_nsIFile" name="Modifying_Paths_with_nsIFile">Modifying Paths with <code>nsIFile</code></h4>
+
+<p>The directory service returns an <code>nsIFile</code> object, but that object points to the application directory and not the file itself. To modify this <code>nsIFile</code> so that it points to the file, you must call the <code>Append</code> method of the <code>nsIFile</code>. <code>Append</code> adds the input string to the path already specified in the <code>nsIFile</code>. On Unix, for example, calling <code>Append("b")</code> on an <code>nsIFile</code> modifies that <code>nsIFile</code> representing <code>/u/home/dougt/a</code> to point to <code>/u/home/dougt/a/b</code>. The next operation on the <code>nsIFile</code> returns results associated with the "b" path. If "a" wasn't a directory, further operations would fail, even if the initial <code>Append</code> was successful. This is why <code>Append</code> is considered a string operation.</p>
+
+<p>目录服务返回一个nsIFile对象, 但nsIFile对象指向的是应用程序目录而并不是文件. 因此为了修改nsIFile对象以指向文件你必须要调用nsIFile的Append函数. Append函数将字符串输入参数追加到已经被指定到nsIFile的路径里. 例如在Unix里, 在一个nsIFile上调用Append("b")将使nsIFile从指向/u/home/dougt/a修改为指向/u/home/dougt/a/b. 在nsIFile上的后续操作返回的结果将是关于"b"这个路径的. 如果"a"不是一个目录, 那么进一步的操作将会失败, 尽管对于Append函数的调用是成功的. 这就是为什么Append函数被认为是对字符串的操作(不进行目录路径的有效性验证).</p>
+
+<p>The <strong>WebLock</strong> component manipulates a file named <code>weblock.txt</code>. The following snippet adjusts the <code>theFile</code> object representing that file:</p>
+
+<p>WebLock组件操作名为weblock.txt的文件, 以下程序片段调整了theFile对象以表示那个文件:</p>
+
+<pre>nsEmbedCString fileName("weblock.txt");
+appDir-&gt;AppendNative(fileName);
+</pre>
+
+<h4 id="Manipulating_Files_with_nsIFile" name="Manipulating_Files_with_nsIFile">Manipulating Files with <code>nsIFile</code></h4>
+
+<p>Once you have an <code>nsIFile</code> object pointing to the file that you're interested in, you can open it and read its contents into memory. There are many ways to do this: You can use Standard ANSI File I/O, or NSPR (see <a href="#The_Netscape_Portable_Runtime_Library">The Netscape Portable Runtime Library</a> below for a brief description of NSPR), or you can use the networking APIs that Gecko provides.</p>
+
+<div class="side-note">
+<p><span id="The_Netscape_Portable_Runtime_Library"><a id="The_Netscape_Portable_Runtime_Library"></a><strong>The Netscape Portable Runtime Library</strong></span></p>
+
+<p>The<em>Netscape Portable Runtime Library</em> (NSPR) is a platform-independent library that sits below XPCOM. As a layer of abstraction above the operating system, the NSPR allows Gecko applications to be platform independent by providing the following system-level facilities:</p>
+
+<ul>
+ <li>Threads</li>
+ <li>Thread synchronization</li>
+ <li>File and network I/O</li>
+ <li>Timing and intervals</li>
+ <li>Memory management</li>
+ <li>Shared library linking</li>
+</ul>
+
+<p>The NSPR is included in the Gecko SDK.</p>
+</div>
+
+<p>To keep things as simple as possible, we'll read the file into memory using standard ANSI file I/O, but for examples and information about how to use<em>necko</em> , the Gecko networking libraries, see <a class="external" href="http://www.mozilla.org/projects/netlib/" rel="freelink">http://www.mozilla.org/projects/netlib/</a>.</p>
+
+<h4 id="Using_nsILocalFile_for_Reading_Data" name="Using_nsILocalFile_for_Reading_Data">Using <code>nsILocalFile</code> for Reading Data</h4>
+
+<p>An <code>nsIFile</code> object returned from the directory service may also implement the <code>nsILocalFile</code> interface, which has a method that will return a <code>FILE</code> pointer that can be used in <code>fread()</code>. To implement the actual read, you need to allocate a buffer the length of the file, use the <code>nsILocalFile</code> interface pointer to obtain a <code>FILE *</code>, use this result with <code>fread</code>, and close the file pointer.</p>
+
+<p>The following code loads the contents of the file referenced by the <code>nsIFile</code> object <code>theFile</code> into the buffer <code>buf</code>:</p>
+
+<pre>nsCOMPtr&lt;nsILocalFile&gt; localFile = do_QueryInterface(theFile);
+if (!localFile)
+ return -1;
+
+PRBool exists;
+rv = theFile-&gt;Exists(&amp;exists);
+if (NS_FAILED(rv))
+ return -1;
+
+char *buf = NULL;
+
+if (exists)
+{
+ // determine file size:
+ PRUint32 fs, numread;
+ PRInt64 fileSize;
+ rv = theFile-&gt;GetFileSize(&amp;fileSize);
+ if (NS_FAILED(rv))
+ return -1;
+
+ // Converting 64 bit value to unsigned int
+ LL_L2UI(fs, fileSize);
+
+ FILE* openFile;
+ rv = localFile-&gt;OpenANSIFileDesc("rw", &amp;openFile);
+ if (NS_FAILED(rv))
+ return -1;
+
+ char *buf = (char *)malloc((fs+1) * sizeof(char));
+ if (!buf)
+ return -1;
+
+ numread = fread(buf, sizeof(char), fs, openFile);
+
+ if (numread != fs)
+ // do something useful.
+
+ // ...
+}
+
+if (buf)
+ free(buf);
+</pre>
+
+<p>The first line of the code calls <code>QueryInterface</code> on <code>theFile</code>, and if that succeeds assigns the new interface pointer to <code>localFile</code>. If the <code>QueryInterface</code> call fails, <code>localFile</code> will have a value of <code>NULL</code>.</p>
+
+<div class="side-note">
+<p>Note that the out parameter of the method <code>GetFileSize</code> is a 64-bit integer. The type of this variable is <code>PRInt64</code>, but this type is not represented as a primitive on all platforms. On some platforms, <code>PRInt64</code> is a <code>struct</code> with two fields - a high and a low 32-bit integer. So operations on this type must use special macros that do the right thing on each platform. On Windows or Linux, for example, it is possible to multiply a <code>PRInt64</code> by a long like this:</p>
+
+<pre>PRInt64 x = 1, y = 2;
+y = x * 2;
+</pre>
+
+<p>However, this same snippet will not compile on a platform like Macintosh OS 9, where you need to use macros to perform the calculation:</p>
+
+<pre>PRInt64 x, y, two;
+LL_I2L(x, 1);
+LL_I2L(y, 2);
+LL_I2L(two, 2);
+LL_MUL(y, x, two);
+</pre>
+
+<p>A full listing of NSPR's <code>long long</code> support can be found at <a class="external" href="http://www.mozilla.org/projects/nspr/" rel="freelink">http://www.mozilla.org/projects/nspr/</a>.</p>
+
+<p>The <strong>WebLock</strong> component doesn't have to deal with files that are longer than 2<sup>32</sup> bytes. Truncating this value to whatever can fit into a 32-bit unsigned integer may not work for every application, but in this case it doesn't really matter.</p>
+</div>
+
+<h4 id="Processing_the_White_List_Data" name="Processing_the_White_List_Data">Processing the White List Data</h4>
+
+<p>There are various ways to process the file data itself. The file <code>weblock.txt</code> consists of URL tokens separated by return characters, which makes them easy to read into a data structure.</p>
+
+<p>The white list file can be read in as soon as the component starts up (i.e., as <strong>WebLock</strong> intercepts the startup notification in the <code>Observe</code> method of the <code>nsIObserver</code> interface that we implement). Since we have only registered to receive a notification when XPCOM starts up, it's a safe assumption that <code>Observe</code> will only be called during the startup event, so we can read the file data in the callback.</p>
+
+<p>After you've read the data into memory, you need to store it in some way to make data access quick and efficient.</p>
+
+<div class="side-note">
+<p><span id="URL_Checking"><a id="URL_Checking"></a><strong>URL Checking</strong></span></p>
+
+<p>The way in which URL checking is implemented in the <strong>WebLock</strong> component is not at all optimal. The <strong>WebLock</strong> component manages a simple linked list of URL strings. A linear search through the data in the white list may not be terribly bad if the number of URLs is under a couple of dozen, but it decays as the list grows. There's also a large bottleneck in the network request. URL data is accessed as in the diagram below:</p>
+
+<p><img alt="Image:urldata-access-in-weblock.png"></p>
+
+<p>You might construct hash values for each of the URL strings instead, or add them to some kind of database. But we leave optimizations and real-world performance for web locking to the reader.</p>
+</div>
+
+<h3 id="iWebLock_Method_by_Method" name="iWebLock_Method_by_Method"><code>iWebLock</code> Method by Method</h3>
+
+<p>The implementation of the <code>iWeblock</code> interface is straightforward. <strong>WebLock</strong> is designed so that the user interface notifies this service when we should go into lock mode. During this time, any new URL request that is not in our list of "good" URLs will be denied. Through scriptable access to the <code>iWebLock</code> interface, the user interface can also add, remove, and enumerate the list of URLs that it knows about.</p>
+
+<h4 id="Lock_and_Unlock" name="Lock_and_Unlock"><code>Lock</code> and <code>Unlock</code></h4>
+
+<p>The <code>lock</code> and <code>unlock</code> methods simply set a Boolean representing state in the object. This Boolean value will be used later to determine if we should be denying URL requests:</p>
+
+<pre>/* void lock (); */
+NS_IMETHODIMP
+WebLock::Lock()
+{
+ mLocked = PR_TRUE;
+ return NS_OK;
+}
+
+/* void unlock (); */
+NS_IMETHODIMP WebLock::Unlock()
+{
+ mLocked = PR_FALSE;
+ return NS_OK;
+}
+</pre>
+
+<h4 id="AddSite" name="AddSite"><code>AddSite</code></h4>
+
+<p>For <code>AddSite</code>, we add a new node to our linked list. The link list nodes contain a <code>char*</code> which points to the string URL that we care about and, of course, a pointer to the next element in the list.</p>
+
+<div class="side-note">
+<p><span id="%3Ccode%3EnsMemory%3C/code%3E_for_Cross-component_Boundaries"><a id="%3Ccode%3EnsMemory%3C/code%3E_for_Cross-component_Boundaries"></a><strong><code>nsMemory</code> for Cross-component Boundaries</strong></span></p>
+
+<p>WebLock maintains ownership of all the memory it allocates, so you can use just about any allocator that you want for <strong>WebLock</strong>, but this is not always the case. In other places, where allocated buffers cross interface boundaries, you must ensure that the correct allocator is used - namely <code>nsMemory</code> - so that the allocators can match the allocation with the deallocation.</p>
+
+<p>Suppose you call <code>malloc</code> from object A and pass this buffer to another object B, for example. But if object B is using a special allocator that does garbage collection, then when object B deletes a buffer allocated by object A's allocator, the results are unpredictable: probably an assertion will be raised, possibly a memory leak, or a crash. The <code>nsMemory</code> class is a wrapper around the <code>nsIMemory</code> interface, whose only implementation is part of XPCOM. When you use <code>nsMemory</code>, you are guaranteed to be using this same memory allocator in all cases, and this avoids the problem described here.</p>
+</div>
+
+<h4 id="RemoveSite" name="RemoveSite"><code>RemoveSite</code></h4>
+
+<p><code>RemoveSite</code> deletes a node from the linked list:</p>
+
+<pre>// a simple link list.
+struct urlNode
+{
+ char* urlString;
+ struct urlNode* next;
+};
+
+/* void addSite (in string url); */
+NS_IMETHODIMP
+WebLock::AddSite(const char *url)
+{
+ // we don't special-case duplicates here
+ urlNode* node = (urlNode*) malloc(sizeof(urlNode));
+ node-&gt;urlString = strdup(url);
+ node-&gt;next = mRootURLNode;
+ mRootURLNode = node;
+
+ return NS_OK;
+}
+
+/* void removeSite (in string url); */
+NS_IMETHODIMP
+WebLock::RemoveSite(const char *url)
+{
+ // find our entry.
+ urlNode* node = mRootURLNode;
+ urlNode* prev = nsnull;
+
+ while (node) // test this!
+ {
+ if (strcmp(node-&gt;urlString, url) == 0)
+ {
+ free(node-&gt;urlString);
+ if (prev)
+ prev-&gt;next = node-&gt;next;
+ free(node);
+ return NS_OK;
+ }
+ prev = node;
+ node = node-&gt;next;
+ }
+
+ return NS_ERROR_FAILURE;
+}
+</pre>
+
+<h4 id="SetSites" name="SetSites"><code>SetSites</code></h4>
+
+<p>The purpose of <code>SetSites</code> is to allow clients to pass an enumeration, or set, of URL strings to add to the white list of URLs. <code>SetSites</code> uses an <code>nsISimpleEnumerator</code> and shows how primitive data can be passed as an <code>nsISupports</code> object. The <code>nsISimpleEnumerator</code> interface is shown in <a href="#The_Web_Locking_Interface">The Web Locking Interface</a>.</p>
+
+<p>The first method returns a Boolean if there are more elements in the set. Internally, the object knows the number of elements it has in its enumeration, and every time a client calls <code>getNext</code>, it decrements a counter - or adjusts a pointer to the next element. When the counter goes to zero or the pointer points to a non-element, <code>hasMoreElements</code> will return false.</p>
+
+<p>There is no way to reset an <code>nsISimpleEnumerator</code>. For example, you can't re-enumerate the set. If you need random access to the elements in a <code>nsISimpleEnumerator</code>, you can read them from the <code>nsISimpleEnumerator</code>, store them in an array, and access them there. The <code>getNext</code> method returns a <code>nsISupports</code> interface pointer.</p>
+
+<p>When you want to pass primitive data types like numbers, strings, characters, <code>void *</code>, and others, the solution is to use one of the <code>nsISupportsPrimitive</code> interfaces. These interfaces wrap primitive data types and derive from <code>nsISupports</code>. This allows types like the strings that represent URLs in the <strong>WebLock</strong> component to be passed though methods that take an <code>nsISupports</code> interface pointer. This becomes clear when when you see the implementation of <code>SetSites</code>:</p>
+
+<pre>NS_IMETHODIMP
+WebLock::SetSites(nsISimpleEnumerator * aSites)
+{
+ PRBool more = PR_TRUE;
+ while (more)
+ {
+ nsCOMPtr&lt;nsISupports&gt; supports;
+ aSites-&gt;GetNext(getter_AddRefs(supports));
+
+ nsCOMPtr&lt;nsISupportsCString&gt; supportsString = do_QueryInterface(supports);
+
+ if (supportsString)
+ {
+ nsEmbedCString url;
+ supportsString-&gt;GetData(url);
+ AddSite(url.get());
+ }
+
+ aSites-&gt;HasMoreElements(&amp;more);
+ }
+
+ return NS_OK;
+}
+</pre>
+
+<h4 id="GetNext" name="GetNext"><code>GetNext</code></h4>
+
+<p><code>GetNext</code> is called with the <code>nsCOMPtr</code> of an <code>nsISupportsCString</code>. <code>nsCOMPtr</code>s are nice because they do whatever <code>QueryInterface</code> calls are necessary under the hood. For example, we know that the <code>GetNext</code> method takes an <code>nsISupports</code> object, but we may not be sure whether the return result supports the interface we want, <code>nsISupportsCString</code>. But after <code>GetNext</code> returns, the <code>nsCOMPtr</code> code takes the out parameter from <code>GetNext</code> and tries to <code>QueryInterface</code> it to the <code>nsCOMPtr</code>'s type. In this case, if the out parameter of <code>GetData</code> does not return something that is <code>QueryInterface</code>-able to an <code>nsISupportsCString</code>, the variable will be set to <code>null</code>. Once you know that you have an <code>nsISupportsCString</code>, you can grab the data from the primitive supports interface.</p>
+
+<p>To get something you can pass into the <code>AddSite</code> method, you need to convert from an <code>nsEmbedCString</code> to a <code>const char*</code>. To do this, you can take advantage of the <code>nsEmbedCString</code> described in <a href="cn/Creating_XPCOM_Components/Using_XPCOM_Utilities_to_Make_Things_Easier#String_Classes_in_XPCOM">String Classes in XPCOM</a>.</p>
+
+<h4 id="GetSites" name="GetSites"><code>GetSites</code></h4>
+
+<p>The implementation of <code>GetSites</code> is more involved. You must construct an implementation of <code>nsISimpleEnumerator</code> and return it when <code>GetSites</code> is called. The class needs to walk the list of <code>urlNode</code>'s for every call to <code>GetNext</code>, so it makes sense for the constructor itself to take an <code>urlNode</code>:</p>
+
+<pre>class myEnumerator : public nsISimpleEnumerator
+{
+ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSISIMPLEENUMERATOR
+
+ myEnumerator(urlNode* node) {
+ NS_INIT_ISUPPORTS()
+ mNode = node;
+ }
+ virtual ~myEnumerator(void) {}
+
+ protected:
+ urlNode* mNode;
+ nsCOMPtr&lt;nsIComponentManager&gt; mCompMgr;
+};
+
+NS_IMPL_ISUPPORTS1(myEnumerator, nsISimpleEnumerator);
+</pre>
+
+<p>The <code>myEnumerator</code> class is going to implement the <code>nsISupports</code> interface and also <code>nsISimpleEnumerator</code>. The only state that it needs to maintain is the current URL node - the one that will be return on the next call to <code>GetNext</code>. There is also an <code>nsCOMPtr</code> to the <code>nsIComponentManager</code>, which is used in every call to <code>GetNext</code> so that you can create <code>nsISupportsCString</code> objects and cache the interface pointer as an optimization.</p>
+
+<h4 id="HasMoreElements" name="HasMoreElements"><code>HasMoreElements</code></h4>
+
+<p><code>HasMoreElements</code> is simple. All you need to do is make sure that <code>mNode</code> isn't <code>null</code>:</p>
+
+<pre>NS_IMETHODIMP
+myEnumerator::HasMoreElements(PRBool* aResult)
+{
+ if (!aResult)
+ return NS_ERROR_NULL_POINTER;
+
+ if (!mNode) {
+ *aResult = PR_FALSE;
+ return NS_OK;
+ }
+
+ *aResult = PR_TRUE;
+ return NS_OK;
+}
+</pre>
+
+<p><code>GetNext</code> needs to create an <code>nsISupportsCString</code> so that you can pass the URL string out through the <code>nsISupports</code> parameter. You must also move <code>mNode</code> to point to the next <code>urlNode</code>.</p>
+
+<pre>static NS_DEFINE_CID(kSupportsCStringCID, NS_SUPPORTS_CSTRING_CID);
+
+NS_IMETHODIMP
+myEnumerator::GetNext(nsISupports** aResult)
+{
+ if (!aResult)
+ return NS_ERROR_NULL_POINTER;
+
+ *aResult = nsnull;
+
+ if (!mNode)
+ return NS_ERROR_FAILURE;
+
+ if (!mCompMgr)
+ {
+ NS_GetComponentManager(getter_AddRefs(mCompMgr));
+ if (!mCompMgr)
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ nsISupportsCString* stringSupports;
+ mCompMgr-&gt;CreateInstance(kSupportsCStringCID,
+ nsnull,
+ NS_GET_IID(nsISupportsCString),
+ (void**)&amp;stringSupports);
+ if (!stringSupports)
+ return NS_ERROR_UNEXPECTED;
+
+ nsEmbedCString str(mNode-&gt;urlString);
+ stringSupports-&gt;SetData(str);
+
+ *aResult = stringSupports; // addref'ed above.
+
+ mNode = mNode-&gt;next;
+
+ return NS_OK;
+}
+</pre>
+
+<p>在实际的<code>GetSites</code>呼叫中, 你需要做的就是产生一个<code>myEnumerator</code>实例并且返回它.</p>
+
+<p>此前,我们建立了一个类并且把它注册到组件管理器。当一个客户端需要获取某个接口的实现时,实际上的对象建立过程隐藏在XPCOM代码中。 但是其中, 你要初始化你自己的<code>nsISimpleEnumerator</code>实现. 这是一个简单的事情,但是你需要注意<code>NS_ADDREF</code>.</p>
+
+<pre>NS_IMETHODIMP
+WebLock::GetSites(nsISimpleEnumerator * *aSites)
+{
+ myEnumerator* enumerator = new myEnumerator(mRootURLNode);
+ if (!enumerator)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ NS_ADDREF(*aSites = enumerator);
+ return NS_OK;
+}
+</pre>
+
+<div class="side-note">
+<p><span id="AddRef,_Releasing,_and_Deleting_Objects"><a id="AddRef,_Releasing,_and_Deleting_Objects"></a><strong>AddRef, Releasing, and Deleting Objects</strong></span></p>
+
+<p>永远不要忘记调用你通过<code>new</code>建立的XPCOM对象的<code>AddRef</code>方法。所有的代码或者活动组件都应该有一个起码一个引用计数。忘记这点可能引起麻烦。</p>
+
+<p>一个相关的警示试你不要忘记永远不要用<code>delete</code>删除一个XPCOM. 当系统的一部分不是释放而是删除一个XPCOM对象的时候,可能会引起几个小时的资源搜索并且引起崩溃。</p>
+</div>
+
+<p>注意上面的实现中,当其他的线程访问链接表的时候<code>myEnumerator</code> 可能变得非法。枚举仅仅表现了访问URL字符串链接表的一个方法。如果你需要枚举成为URL字符串链表的一个快照,你需要重构这个实现让枚举持有一个链表的copy。</p>
+
+<p>当组件中止的时候,你也需要把链表写到磁盘里并且释放空间。我们把这个作为练习留给读者。</p>
+
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/Creating_XPCOM_Components:Using_XPCOM_Utilities_to_Make_Things_Easier" style="float: left;">« 上一页</a><a href="/zh-CN/docs/Creating_XPCOM_Components:Finishing_the_Component">下一页 »</a></p>
+</div> <p></p><div class="licenseblock">
+<p>Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the <a class="external" href="http://www.opencontent.org/openpub/" rel="noopener">Open Publication License</a>, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.</p>
+</div><p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/using_xpcom_components/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/using_xpcom_components/index.html
new file mode 100644
index 0000000000..a0a5b301ba
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/using_xpcom_components/index.html
@@ -0,0 +1,311 @@
+---
+title: 创建_XPCOM_组件/使用_XPCOM_组件
+slug: Mozilla/Tech/XPCOM/Guide/Creating_components/Using_XPCOM_Components
+tags:
+ - XPCOM
+ - 所有分类
+translation_of: Mozilla/Tech/XPCOM/Guide/Creating_components/Using_XPCOM_Components
+---
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/创建_XPCOM_组件:XPCOM_简介" style="float: left;">« 上一页</a><a href="/zh-CN/docs/Creating_XPCOM_Components:Component_Internals">下一页 »</a></p>
+</div><p></p>
+
+<p>创建一个新的 XPCOM 组件, 特别是在我们设计一个供别人使用的组件接口的时候, 最好方式是参照已有的组件. 我们在编写 <a href="cn/Creating_XPCOM_Components/Starting_WebLock">Starting WebLock</a> 这个例子的时候, 也是这么做的.</p>
+
+<p>Mozilla 浏览器应用是复杂的, 模块化的 XPCOM 客户程序. 实际上, 基本上所有与浏览器相关的功能都被定义成了组件的形式, 包括网页间的跳转, 窗口管理, cookie 管理, 书签, 安全, 搜索, 润色等等的其他功能, 这些功能都是由组件的接口提供的. Mozilla<em>就是</em>一堆 XPCOM 组件.</p>
+
+<p>本章将讨论 Mozilla 是如何使用象 CookieManager 这样的 XPCOM 对象, 然后根据这些例子我们定义 WebLock 组件的访问接口.</p>
+
+<h3 id=".E7.BB.84.E4.BB.B6.E7.9A.84.E4.BE.8B.E5.AD.90" name=".E7.BB.84.E4.BB.B6.E7.9A.84.E4.BE.8B.E5.AD.90">组件的例子</h3>
+
+<p>可以在这里 <a href="cn/XPCOM_API_Reference">XPCOM API Reference</a> 找到下面要描述的组件. 我们要了解的是象本节中所给出的组件是如何被 Mozilla 浏览器获取和使用的.</p>
+
+<h4 id="Cookie_.E7.AE.A1.E7.90.86.E5.99.A8" name="Cookie_.E7.AE.A1.E7.90.86.E5.99.A8">Cookie 管理器</h4>
+
+<p>Cookie 管理是以组件形式向 Mozilla 浏览器提供支持的众多组件之一, 这些组件可以被重用在需要类似功能的应用中. 当用户通过 Cookie 管理器对话框来观察, 组织, 或者删除 cookies 的时候, Cookie 管理器在背后默默的工作. <a href="#Cookie_管理器对话框">Cookie 管理器对话框</a>负责向用户提供 Cookie 管理器的 UI 界面<sup><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Guide/Creating_components/Using_XPCOM_Components#endnote_cookie-manager-ui">[cookie-manager-ui]</a></sup>.</p>
+
+<p><span id="Cookie_%E7%AE%A1%E7%90%86%E5%99%A8%E5%AF%B9%E8%AF%9D%E6%A1%86"><a id="Cookie_%E7%AE%A1%E7%90%86%E5%99%A8%E5%AF%B9%E8%AF%9D%E6%A1%86"></a><strong>Cookie 管理器对话框</strong></span></p>
+
+<p><img alt="Image:cookie_mgr_dlog.png"></p>
+
+<p>对话框是用 XUL (XML UI 语言) 和 JavaScript 语言编写, 使用称为<em>XPConnect</em> 的组件无缝连接到 Cookie 管理器组件(参看下面的 <a href="#从接口连接到组件">从接口连接到组件</a>). XUL 只是一种暴露 Cookie 管理器功能的方式, 但是却是 Mozilla 环境下最有用的方式之一.</p>
+
+<p>CookieManager 组件的功能通过 <code>nsICookieManager</code> 接口提供, 接口的方法如下:</p>
+
+<p><span id="%3Ccode%3EnsICookieManager%3C/code%3E_%E6%8E%A5%E5%8F%A3"><a id="%3Ccode%3EnsICookieManager%3C/code%3E_%E6%8E%A5%E5%8F%A3"></a><strong><code>nsICookieManager</code> 接口</strong></span></p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>removeAll</code></td>
+ <td>删除 cookie 列表中所有的 cookies.</td>
+ </tr>
+ <tr>
+ <td><code>enumerator</code></td>
+ <td>通过 cookie 列表枚举.</td>
+ </tr>
+ <tr>
+ <td><code>remove</code></td>
+ <td>从列表中删除某个 cookie .</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>XPCOM 中所有的接口必须固定, 虽然组件对接口的实现会有所变化. 接口都是<em>public</em> 的, 相对的, 接口实现是 private 的<sup><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Guide/Creating_components/Using_XPCOM_Components#endnote_private-xpcom-interfaces">[private-xpcom-interfaces]</a></sup>. 当用户选中 cookie 列表中的一个 cookie, 点击 Remove 按钮, <code>nsICookieManager</code> 接口的 <code>Remove</code> 方法被调用. CookieManager 组件执行该函数, 选中的组件就被删除了.</p>
+
+<p>下面的<a href="#从_JavaScript_中访问_CookieManager_组件">从 JavaScript 中访问 CookieManager 组件</a>代码, 展示了如何从 JavaScript 中调用 <code>Remove()</code> 方法:</p>
+
+<p><span id="%E4%BB%8E_JavaScript_%E4%B8%AD%E8%AE%BF%E9%97%AE_CookieManager_%E7%BB%84%E4%BB%B6"><a id="%E4%BB%8E_JavaScript_%E4%B8%AD%E8%AE%BF%E9%97%AE_CookieManager_%E7%BB%84%E4%BB%B6"></a><strong>从 JavaScript 中访问 CookieManager 组件</strong></span></p>
+
+<pre>// xpconnect to cookiemanager
+// get the cookie manager component in JavaScript
+var cmgr = Components.classes["@mozilla.org/cookiemanager;1"]
+ .getService();
+cmgr = cmgr.QueryInterface(Components.interfaces.nsICookieManager);
+
+// called as part of a largerDeleteAllCookies() function
+function FinalizeCookieDeletions() {
+ for (var c=0; c&lt;deletedCookies.length; c++) {
+ cmgr.remove(deletedCookies[c].host,
+ deletedCookies[c].name,
+ deletedCookies[c].path);
+ }
+ deletedCookies.length = 0;
+}
+</pre>
+
+<div class="side-note">
+<p><span id="%E4%BB%8E%E6%8E%A5%E5%8F%A3%E8%BF%9E%E6%8E%A5%E5%88%B0%E7%BB%84%E4%BB%B6"><a id="%E4%BB%8E%E6%8E%A5%E5%8F%A3%E8%BF%9E%E6%8E%A5%E5%88%B0%E7%BB%84%E4%BB%B6"></a><strong>从接口连接到组件</strong></span></p>
+
+<p>Mozilla 中使用的从 JavaScript 访问 XPCOM 组件的技术称为<em>XPConnect</em>, XPConnect 也是一个组件.</p>
+
+<p>XPConnect 把应用程序代码与 Mozilla 浏览器, 基于 Gecko 的 XUL, 和象 xpcshell 这样的 JavaScript 环境绑定在一起.</p>
+
+<p>xpcshsell 是 Mozilla 内嵌的 XPCOM 工具, 它是 JavaScript 的命令行解释器.</p>
+
+<p>参看 <a class="external" href="http://www.mozilla.org/scriptable/" rel="freelink">http://www.mozilla.org/scriptable/</a>, 获取更多关于 XPConnect 和 JavaScript 的信息.</p>
+</div>
+
+<p>上面展现的技术当然并不是 XPCOM 的全部, 但是却是一个重要的方面. XPCOM 强加的契约打开了一扇通往<em>二进制互操作</em>技术的大门. - 这是一种能够在运行时刻访问, 使用, 重用 XPCOM 组件的技术, 这种技术能够保证用某种语言编写的组件能够被其他的语言所访问.</p>
+
+<p>在 Mozilla 浏览器中, 组件常常通过接口在 JavaScript 中访问, 搜索 Mozilla 的源代码, 会发现 CookieManager 组件<em>只是</em>在 JavaScript 中被调用. 在本教程中, 我们也使用这种方式来访问它<sup><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Guide/Creating_components/Using_XPCOM_Components#endnote_教程中使用的_coocki_管理器">[教程中使用的 coocki 管理器]</a></sup>.</p>
+
+<div class="side-note">
+<p><span id="JavaScript_%E4%B8%8E_Mozilla"><a id="JavaScript_%E4%B8%8E_Mozilla"></a><strong>JavaScript 与 Mozilla</strong></span></p>
+
+<p>JavaScript 是 Mozilla 浏览器的喉舌, 它把自己与 XPCOM 紧紧地绑定在一起. XPCOM 的这种<em>可扩展</em>能力 - 从 XPConnect 绑定的语言中访问组件的能力, 是 XPCOM 的一个关键属性.</p>
+</div>
+
+<h4 id="WebBrowserFind_.E7.BB.84.E4.BB.B6" name="WebBrowserFind_.E7.BB.84.E4.BB.B6"><code>WebBrowserFind</code> 组件</h4>
+
+<p>组件的应用是广泛的: 在浏览这样的高级应用中, 会有 <code>nsWebBrowserFind</code> 这样的接口, 它提供 <code>find()</code> 和 <code>findNext()</code> 方法用于在网页上查找特定内容. 在一些低级应用中, 会提供数据管理这样的功能. 虽然 Mozilla 并不能将所有的 API 都写成 XPCOM 组件的形式, 但是绝大多数浏览器的典型功能都是用 XPCOM 的组件形式实现的, 因此可以被嵌入和扩展.</p>
+
+<p>除了 CookieManager 组件, 这里还要介绍一个 WebBrowserFind 组件. 它实现的 <code>nsIWebBrowserFind</code> 接口见下表 <a href="#nsIWebBrowserFind_接口">nsIWebBrowserFind 接口</a>.</p>
+
+<p><span id="nsIWebBrowserFind_%E6%8E%A5%E5%8F%A3"><a id="nsIWebBrowserFind_%E6%8E%A5%E5%8F%A3"></a><strong>nsIWebBrowserFind 接口</strong></span></p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>findNext</code></td>
+ <td>找到字符串出现的下一个位置.</td>
+ </tr>
+ <tr>
+ <td><code>findBackwards</code></td>
+ <td>布尔类型属性值, 控制 <code>findNext()</code> 方法向前/向后搜索.</td>
+ </tr>
+ <tr>
+ <td><code>searchFrames</code></td>
+ <td>布尔类型属性值, 标识是否搜索当前页面的子框(subframes).</td>
+ </tr>
+ <tr>
+ <td><code>matchCase</code></td>
+ <td>布尔类型属性值, 标识是否按照大小写匹配搜索网页.</td>
+ </tr>
+ <tr>
+ <td><code>entireWord</code></td>
+ <td>布尔类型属性值, 标识是否匹配整个词.</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>一旦我们使用接口来获的了某个组件, 我们就可以询问该组件是否支持其他的接口. 这种基本服务由 <code>nsISupports</code> 接口提供, 会由所有的 XPCOM 组件继承; 它允许我们查询组件的接口, 并在接口之间进行切换; 它展现了 XPCOM 的<em>运行时刻确定类型</em>的能力. 它由 <code>QueryInterface</code> 方法实现, 我们将在后面<a href="cn/Creating_XPCOM_Components/%e4%bb%80%e4%b9%88%e6%98%af_XPCOM%3f">什么是 XPCOM?</a>一章中介绍. <a href="cn/XPCOM_API_Reference">XPCOM API Reference</a> 中提供了完整的 XPCOM 组件的索引.</p>
+
+<h4 id="WebLock_.E7.BB.84.E4.BB.B6" name="WebLock_.E7.BB.84.E4.BB.B6"><strong>WebLock</strong> 组件</h4>
+
+<p>现在我们把 <strong>WebLock</strong> 组件看成另一个 XPCOM 组件的例子. 在面向对象编程中, 通常是先设计接口 - 首先定义要提供的功能, 而不是考虑如何实现这些功能. 因此我们把实现这个组件的细节问题放到下一章, 这一章先考虑从外部如何看待这个组件. - 即定义 WebLock 组件的接口.</p>
+
+<p><span id="IWebLock_%E6%8E%A5%E5%8F%A3"><a id="IWebLock_%E6%8E%A5%E5%8F%A3"></a><strong>IWebLock 接口</strong></span></p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>lock</code></td>
+ <td>锁定浏览器到当前站点, 或者是磁盘上保存的某个白名单上的站点.</td>
+ </tr>
+ <tr>
+ <td><code>unlock</code></td>
+ <td>解开浏览器锁定, 开放访问所有站点.</td>
+ </tr>
+ <tr>
+ <td><code>addSite</code></td>
+ <td>添加一个新的站点到白名单.</td>
+ </tr>
+ <tr>
+ <td><code>removeSite</code></td>
+ <td>从白名单上删除某个站点.</td>
+ </tr>
+ <tr>
+ <td><code>sites</code></td>
+ <td>枚举白名单上的站点.</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>WebLock 组件就是要实现上面接口定义的功能. 它在浏览器启动的时候, 注册自己. 当用户或者管理员点击浏览器上的 weblock 图标时, 类厂会创建对象实例.</p>
+
+<h3 id="Mozilla_.E4.B8.AD.E4.BD.BF.E7.94.A8.E7.9A.84.E7.BB.84.E4.BB.B6" name="Mozilla_.E4.B8.AD.E4.BD.BF.E7.94.A8.E7.9A.84.E7.BB.84.E4.BB.B6">Mozilla 中使用的组件</h3>
+
+<p>那么我们应该如何获得组件, 然后如何在 Mozilla 中使用它呢? 我们在前面已经看到了一小段 JavaScript 代码, 但是我们并没有解释一般情况下该如何获得 XPCOM 组件.</p>
+
+<p>这一节讨论 Mozilla 中实际使用的组件例子. 本节分成三部分: 一部分是关于该如何在 Mozilla 上找到组件. 其他两个部分是关于该如何访问这些组件.</p>
+
+<h4 id=".E6.9F.A5.E6.89.BE_Mozilla_.E7.BB.84.E4.BB.B6" name=".E6.9F.A5.E6.89.BE_Mozilla_.E7.BB.84.E4.BB.B6">查找 Mozilla 组件</h4>
+
+<p>本书试图向读者提供关于 XPCOM 组件和当前冻结的接口的索引信息. <a class="external" href="http://www.mozilla.org/projects/embedding/">Mozilla 嵌入工程</a>跟踪了当前冻结的接口.</p>
+
+<p>Mozilla 包含了 Gecko 提供的查找和显示组件信息的工具 -<em>XPCOM 组件观察器</em><a class="external" href="http://lxr.mozilla.org/">LXR</a>.</p>
+
+<p>提供 XPCOM 组件信息的主要问题是, Mozilla 接口在不断的发展, 试图选择一个冻结的断面是困难的. 组件观察器的实现并没有考虑组件是否已被冻结, 在 LXR 中我们会发现, 被冻结的接口会在头部标记 <code>@status frozen</code>.</p>
+
+<h5 id="XPCOM_.E7.BB.84.E4.BB.B6.E8.A7.82.E5.AF.9F.E5.99.A8" name="XPCOM_.E7.BB.84.E4.BB.B6.E8.A7.82.E5.AF.9F.E5.99.A8">XPCOM 组件观察器</h5>
+
+<p><a class="external" href="http://www.hacksrus.com/~ginda/cview">组件观察器</a> 是一个可选安装的浏览器插件.</p>
+
+<p><span id="XPCOM_%E7%BB%84%E4%BB%B6%E8%A7%82%E5%AF%9F%E5%99%A8"><a id="XPCOM_%E7%BB%84%E4%BB%B6%E8%A7%82%E5%AF%9F%E5%99%A8"></a><strong>XPCOM 组件观察器</strong></span></p>
+
+<p><img alt="Image:using-component-viewer.png"></p>
+
+<p>在上面的图中, 左列显示的是以<em>gtx</em> 字符串搜索契约 ID 得到的组件子集, 右列是左列选中组件实现的接口.</p>
+
+<p>XPCOM 观察器在获取组件的大致信息的时候非常有用, 但是要知道组件观察器显示的是<em>所有</em>的组件, 有些组件并不稳定, 组件的接口可能会在后续版本中变化, 所以要慎重选取我们自己工程中使用的组件.</p>
+
+<p><span class="comment">XXX mediawiki is t3h suxx0r</span> <span class="comment">XXX give me my C++</span></p>
+
+<h4 id=".E5.9C.A8_Cpp_.E4.BB.A3.E7.A0.81.E4.B8.AD.E4.BD.BF.E7.94.A8_XPCOM_.E7.BB.84.E4.BB.B6" name=".E5.9C.A8_Cpp_.E4.BB.A3.E7.A0.81.E4.B8.AD.E4.BD.BF.E7.94.A8_XPCOM_.E7.BB.84.E4.BB.B6">在 Cpp 代码中使用 XPCOM 组件</h4>
+
+<p>XPConnect 把对 XPCOM 组件作为 JavaScript 对象, 使得对 XPCOM 组件的访问变得非常简单, 从 C++ 代码中访问 XPCOM 要复杂一些.</p>
+
+<p><a href="#从_Cpp_代码管理_Cookies">从 Cpp 代码管理 Cookies</a> 以 C++ 代码重新实现了<a href="#从_JavaScript_中访问_CookieManager_组件">从 JavaScript 中访问 CookieManager 组件</a>的功能.</p>
+
+<p><span id="%E4%BB%8E_Cpp_%E4%BB%A3%E7%A0%81%E7%AE%A1%E7%90%86_Cookies"><a id="%E4%BB%8E_Cpp_%E4%BB%A3%E7%A0%81%E7%AE%A1%E7%90%86_Cookies"></a><strong>从 Cpp 代码管理 Cookies</strong></span></p>
+
+<pre>nsCOMPtr&lt;nsIServiceManager&gt; servMan;
+nsresult rv = NS_GetServiceManager(getter_AddRefs(servMan));
+if (NS_FAILED(rv))
+ return -1;
+
+nsCOMPtr&lt;nsICookieManager&gt; cookieManager;
+rv = servMan-&gt;GetServiceByContractID("@mozilla.org/cookiemanager",
+ NS_GET_IID(nsICookieManager),
+ getter_AddRefs(cookieManager));
+
+if (NS_FAILED(rv))
+ return -1;
+
+PRUint32 len;
+deletedCookies-&gt;GetLength(&amp;len);
+
+for (int c=0; c&lt;len; c++)
+ cookieManager-&gt;Remove(deletedCookies[c].host,
+ deletedCookies[c].name,
+ deletedCookies[c].path,
+ PR_FALSE);
+</pre>
+
+<p><span class="comment">XXX: In the original document, there were only the first three parameters to the |Remove| call. I added |PR_TRUE| as a fourth parameter because the interface seems to require it: <a class="external" href="http://lxr.mozilla.org/mozilla/source/netwerk/cookie/public/nsICookieManager.idl#64" rel="freelink">http://lxr.mozilla.org/mozilla/sourc...Manager.idl#64</a> This problem also appears in the JavaScript version below, and I've added |false| as a fourth parameter there as well.</span></p>
+
+<p>如果我们的应用是用 C++ 编写, <a href="#从_Cpp_代码管理_Cookies">从 Cpp 代码管理 Cookies</a> 这段代码向我们提供了很好的模板.</p>
+
+<h4 id="XPConnect:_.E5.9C.A8.E8.84.9A.E6.9C.AC.E4.B8.AD.E4.BD.BF.E7.94.A8_XPCOM_.E7.BB.84.E4.BB.B6" name="XPConnect:_.E5.9C.A8.E8.84.9A.E6.9C.AC.E4.B8.AD.E4.BD.BF.E7.94.A8_XPCOM_.E7.BB.84.E4.BB.B6">XPConnect: 在脚本中使用 XPCOM 组件</h4>
+
+<p>在本章开始我们讨论了CookieManager组件,他提供了一个很好的例子来说明如何使用javascript访问组件.在下面的代码片断里你可以看到如何通过getService()方法创建一个CookieManager组件对象,并且通过它提供的功能来让我们从用户界面来读取和删除cookies.</p>
+
+<p><span id="Managing_Cookies_from_JavaScript"><a id="Managing_Cookies_from_JavaScript"></a><strong>Managing Cookies from JavaScript</strong></span></p>
+
+<pre>var cmgr = Components.classes["@mozilla.org/cookiemanager;1"]
+ .getService();
+cmgr = cmgr.QueryInterface(Components.interfaces.nsICookieManager);
+
+function loadCookies() {
+ // load cookies into a table
+ var enumerator = cmgr.enumerator;
+ var count = 0;
+ var showPolicyField = false;
+ while (enumerator.hasMoreElements()) {
+ var nextCookie = enumerator.getNext();
+ nextCookie = nextCookie.QueryInterface(Components.interfaces.nsICookie);
+ /* .... */
+}
+function FinalizeCookieDeletions() {
+ for (var c=0; c&lt;deletedCookies.length; c++) {
+ cmgr.remove(deletedCookies[c].host,
+ deletedCookies[c].name,
+ deletedCookies[c].path,
+ false);
+ }
+ deletedCookies.length = 0;
+}
+</pre>
+
+<p><span class="comment">XXX: In the original document, there were only the first three parameters to the |remove| call. I added |false| as a fourth parameter because the interface seems to require it: <a class="external" href="http://lxr.mozilla.org/mozilla/source/netwerk/cookie/public/nsICookieManager.idl#64" rel="freelink">http://lxr.mozilla.org/mozilla/sourc...Manager.idl#64</a> This problem also appears in the C++ version above, and I've added |PR_FALSE| as a fourth parameter there as well.</span></p>
+
+<p>除了CookieManager被调用的方法以外(也就是<code>cookiemanager.remove</code>(他会映射到<code>remove()</code><a href="#The_&lt;code>nsICookieManager&lt;/code>_Interface">The <code>nsICookieManager</code> Interface</a>),请注意那些在Javascript中反映XPCOM组件的专门的XPConnect对象和方法。</p>
+
+<p><code>Components</code> 是用来控制到组件连接的JavaScript对象, 而<code>classes</code> 是一组所有你可以根据契约ID来查询的对象。为了在Javascript中实例化XPCOM组件,你创建一个新的<code>Component</code>对象同时传入你所需要查询的组件契约ID,返回的可能是一个singleton或者一个实例。</p>
+
+<pre>var cmgr = Components.classes["@mozilla.org/cookiemanager;1"]
+ .getService();
+</pre>
+
+<p><code>cookiemanager</code> 对象的结果提供组件的所有在IDL中编译好然后编译到类型库中的方法的入口。 使用CookieManager组件, 你可以写如下的代码来完成从系统中清除所有cookies的操作:</p>
+
+<pre>cmgr = Components.classes["@mozilla.org/cookiemanager;1"]
+ .getService();
+cmgr = cmgr.QueryInterface(Components.interfaces.nsICookieManager);
+
+// delete all cookies
+function trashEm() {
+ cmgr.removeAll();
+}
+</pre>
+
+<p>这个例子所展示的另外一个关键的XPConnect特性的是可以在所有从XPCOM映射到javascript的对象上执行的<code>QueryInterface</code>方法。如同在C++中, 你可以使用这个方法询问给定对象的别的接口。</p>
+
+<div class="side-note">
+<p><span id="Services_Versus_Regular_Instances"><a id="Services_Versus_Regular_Instances"></a><strong>Services Versus Regular Instances</strong></span></p>
+
+<p>到底让客户把你的组件作为一个实例还是服务是一个设计问题,你应当在你的组件文挡中进行描述。实际上,例子中通过方法<code>createInstance()调用</code><code>getService()</code>方法的方法实际上也可以是对组件对象调用并且缓存结果,并让他做为一个singlenton而不是实例。</p>
+
+<p>用来建立服务的singleton设计模式在<a href="cn/Creating_XPCOM_Components/What_is_XPCOM%3f#XPCOM_Services">XPCOM Services</a>进行描述。</p>
+</div>
+
+<p>请记住,<code>QueryInterface</code>让你查询一个对象所支持的接口。在<a href="#The_&lt;code>nsICookieManager&lt;/code>_Interface">The <code>nsICookieManager</code> Interface</a>的代码片断中, <code>QueryInterface</code>方法被用来从eunumerator中获得<code>nsICookie</code>接口,从而, 比如说, JavaScript代码就可以获得每个cookie的<code>value</code>和<code>name</code>属性。</p>
+
+<ol>
+ <li><div class="blockIndicator note"><strong>Note:</strong> cookie-manager-ui</div> 注意接口不是组件的一部分. XPCOM通过Mozilla's Cross Platform Front End (XPFE)和其他的用户接口使使用CookieManager这样的组件变得容易,但是组件本身并不提供自身的UI。</li>
+</ol>
+
+<ol>
+ <li><div class="blockIndicator note"><strong>Note:</strong> private-xpcom-interfaces</div>这方面也有例外. 一些XPCOM接口也可以是private并且不是作为公用的. Private接口和在IDL中公开的接口要求有所不同。</li>
+</ol>
+
+<ol>
+ <li><div class="blockIndicator note"><strong>Note:</strong> cookie-manager-in-tutorial</div> CookieManager组件用来支持本教程所描述的网页所定功能。</li>
+</ol>
+
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/创建_XPCOM_组件:XPCOM_简介" style="float: left;">« 上一页</a><a href="/zh-CN/docs/Creating_XPCOM_Components:Component_Internals">下一页 »</a></p>
+</div> <p></p><div class="licenseblock">
+<p>Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the <a class="external" href="http://www.opencontent.org/openpub/" rel="noopener">Open Publication License</a>, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.</p>
+</div><p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/using_xpcom_utilities_to_make_things_easier/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/using_xpcom_utilities_to_make_things_easier/index.html
new file mode 100644
index 0000000000..98bb510dd8
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/guide/creating_components/using_xpcom_utilities_to_make_things_easier/index.html
@@ -0,0 +1,388 @@
+---
+title: 创建XPCOM组件/使用XPCOM工具类让事情变得简单
+slug: >-
+ Mozilla/Tech/XPCOM/Guide/Creating_components/Using_XPCOM_Utilities_to_Make_Things_Easier
+tags:
+ - XPCOM
+ - 所有分类
+translation_of: >-
+ Mozilla/Tech/XPCOM/Guide/Creating_components/Using_XPCOM_Utilities_to_Make_Things_Easier
+---
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/Creating_XPCOM_Components:Creating_the_Component_Code" style="float: left;">« 上一页</a><a href="/zh-CN/docs/Creating_XPCOM_Components:Starting_WebLock">下一页 »</a></p>
+</div><p></p>
+
+<p>本章回顾你已经在教程第一部分建立的代码 (see <a href="cn/Creating_XPCOM_Components/Creating_the_Component_Code#webLock1.cpp">webLock1.cpp</a> in the previous chapter) 并且使用 XPCOM 工具类让代码更容易更有效. 同时,介绍一个在XPCOM和Gecko API中广泛使用基本的字符串类型.</p>
+
+<p>作为起点,第一部分描述可以替代<code>webLock1.cpp</code>中的很多代码的<em>C++ 宏</em> . 很多用来完成软件组织和组件注册的代码都可以缩减为精简的数据结构和宏代码.</p>
+
+<h3 id="XPCOM_Macros" name="XPCOM_Macros">XPCOM Macros</h3>
+
+<p>XPCOM 架构包含了一系列宏让C++开发变得简单. 尽管有某些重叠(例如,高层的宏可以用其他的宏来组织),他们通常可以组织成如下的类别.</p>
+
+<h4 id="Generic_XPCOM_Module_Macros" name="Generic_XPCOM_Module_Macros">Generic XPCOM Module Macros</h4>
+
+<p>The work in the <a href="cn/Creating_XPCOM_Components/Creating_the_Component_Code">previous chapter</a> was useful in setting up the generic component code. But there are only a few places in that code that are unique to the <strong>WebLock</strong> component, and it was a lot of typing. To write a different component library, you could copy the listing at the end of the chapter, change very little, and paste it into a new project. To avoid these kinds of redundancies, to regulate the way generic code is written, and to save typing, XPCOM provides<em>generic module macros</em> that expand into the module code you've already seen.</p>
+
+<p>Since these macros expand into "generic" implementations, they may not offer as much flexibility as you have when you are writing your own implementation. But they have the advantage of allowing much more rapid development. To get an idea about how much can be handled with the macros described in this section, compare the code listing in <a href="#weblock2.cpp">weblock2.cpp</a> at the end of the chapter with <a href="cn/Creating_XPCOM_Components/Creating_the_Component_Code#webLock1.cpp">webLock1.cpp</a> in the previous chapter.</p>
+
+<p>The module macros include one set of macros that define the exported <code>NSGetModule</code> entry point, the required <code>nsIModule</code> implementation code and another that creates a generic factory for your implementation class. Used together, these macros can take care of a lot of the component implementation code and leave you working on the actual logic for your component.</p>
+
+<div class="side-note">
+<p>Note that all of the macros described in this section are similar but are used in slightly different situations. Some differ only in whether or not a method is called when the module is created and/or destroyed. <a href="#XPCOM_Module_Macros">XPCOM Module Macros</a> lists the macros discussed in this section.</p>
+</div>
+
+<p><span id="XPCOM_Module_Macros"><a id="XPCOM_Module_Macros"></a><strong>XPCOM Module Macros</strong></span></p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">Macro</td>
+ <td class="header">Description</td>
+ </tr>
+ <tr>
+ <td><code>NS_IMPL_NSGETMODULE(name, components)</code></td>
+ <td>Implements the <code>nsIModule</code> interface with the module name of <code>name</code> and the component list in <code>components</code>.</td>
+ </tr>
+ <tr>
+ <td><code>NS_IMPL_NSGETMODULE_WITH_CTOR(name, components, ctor)</code></td>
+ <td>Same as above but allows for a special function to be called when the module is created.</td>
+ </tr>
+ <tr>
+ <td><code>NS_IMPL_NSGETMODULE_WITH_DTOR(name, components, dtor)</code></td>
+ <td>Same as the first macro but allows for a special function to be called when the module is destroyed.</td>
+ </tr>
+ <tr>
+ <td><code>NS_IMPL_NSGETMODULE_WITH_CTOR_DTOR(name, components, ctor, dtor)</code></td>
+ <td>This combines the last two macros so that you can define functions to be called at the construction and destruction of the module object.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h5 id="Module_Implementation_Macros" name="Module_Implementation_Macros">Module Implementation Macros</h5>
+
+<p>The general case is to use <code>NS_IMPL_NSGETMODULE</code>, which doesn't take any callbacks, but all the macros follow the same general pattern. All of these macros work on an array of structures represented by the <code>components</code> parameter. Each structure describes a CID that is to be registered with XPCOM.</p>
+
+<p>The first parameter for each of these macros is an arbitrary string that names the module. In a debugging environment, this string will be printed to the screen when the component library is loaded or unloaded. You should pick a name that makes sense and helps you keep track of things. The four required parts<sup><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Guide/Creating_components/Using_XPCOM_Utilities_to_Make_Things_Easier#endnote_other-parts">[other-parts]</a></sup> of the structure contain the following information:</p>
+
+<ul>
+ <li>A human readable class name</li>
+ <li>the class ID (CID)</li>
+ <li>the contract ID (an optional but recommended argument)</li>
+ <li>a constructor for the given object</li>
+</ul>
+
+<pre>static const nsModuleComponentInfo components[] =
+{
+ { "Pretty Class Name",
+ CID,
+ CONTRACT_ID,
+ Constructor
+ },
+ // ...
+};
+</pre>
+
+<p>The important thing to note in the fictitious listing above is that it can support multiple components in a module. Modules such as the networking libraries in Gecko ("necko") have over 50 components declared in a single <code>nsModuleComponentInfo</code> array like this.</p>
+
+<p>The first entry of the <code>nsModuleComponentInfo</code> above is the name of the component. Though it isn't used that much internally at the present time, this name should be something that meaningfully describes the module.</p>
+
+<p>The second entry of the <code>nsModuleComponentInfo</code> is the CID. The usual practice is to put the class ID (CID) into a <code>#define</code> and use the define to declare the CID in the components list. Many CIDs take the following form:</p>
+
+<pre>#define NS_IOSERVICE_CID \
+{ /* 9ac9e770-18bc-11d3-9337-00104ba0fd40 */ \
+ 0x9ac9e770, \
+ 0x18bc, \
+ 0x11d3, \
+ {0x93, 0x37, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
+}
+</pre>
+
+<p>The next entry is the Contract ID string, which is also usually defined in a <code>#define</code> in a header file.</p>
+
+<p>These three entries constitute the required parameters for the <code>RegisterFactoryLocation</code> method we looked at in the prior chapter. When you use these implementation macros, you must declare a constructor for the object, and this keeps you from having to write a factory object.</p>
+
+<h5 id="Factory_Macros" name="Factory_Macros">Factory Macros</h5>
+
+<p>The factory macro makes it easy to write factory implementations. Given the class name <code>ConcreteClass</code>, the factory macro declaration is:</p>
+
+<pre>NS_GENERIC_FACTORY_CONSTRUCTOR(ConcreteClass)
+</pre>
+
+<p>This results in a function called <code>ConcreteClassConstructor</code> that can be used in the <code>nsModuleComponentInfo</code> structure.</p>
+
+<pre>#include "nsIGenericFactory.h"
+
+static const nsModuleComponentInfo components[] =
+{
+ { "Pretty Class Name",
+ SAMPLE_CID,
+ "@company.com/sample",
+ SampleConstructor
+ }
+}
+
+NS_IMPL_NSGETMODULE(nsSampleModule, components)
+</pre>
+
+<p>Most of the components in the Mozilla browser client use this approach.</p>
+
+<h4 id="Common_Implementation_Macros" name="Common_Implementation_Macros">Common Implementation Macros</h4>
+
+<p>Every XPCOM object implements <code>nsISupports</code>, but writing this implementation over and over is tedious. Unless you have very special requirements for managing reference counting or handling interface discovery, the<em>implementation macros</em> that XPCOM provides can be used. Instead of implementing the <code>nsISupports</code> yourself, <code>NS_IMPL_ISUPPORTS1</code> can expand to the implementation of <code>AddRef</code>, <code>Release</code>, and <code>QueryInterface</code> for any object.</p>
+
+<pre>NS_IMPL_ISUPPORTS1(classname, interface1)
+</pre>
+
+<p>Also, if you implement more than one interface, you can simply change the <code>1</code> in the macro to the number of interfaces you support and list the interfaces, separated by commas. For example:</p>
+
+<pre>NS_IMPL_ISUPPORTS2(classname, interface1, interface2)
+NS_IMPL_ISUPPORTSn(classname, interface1, ..., interfacen)
+</pre>
+
+<p>These macros automatically add the <code>nsISupports</code> entry for you, so you don't need to do something like this:</p>
+
+<pre class="eval">NS_IMPL_ISUPPORTS2(classname, interface1, <strong>nsISupports</strong>)
+</pre>
+
+<p><br>
+ Take a close look at the above example. Note that it uses the actual name of the interface and not an IID. Inside the macro, the interface name expands to <code>NS_GET_IID()</code>, which is another macro that extracts the IID from the generated header of the interface. When an interface is written in XPIDL, the headers include static declarations of their IIDs. On any interface that is generated by XPIDL, you can call <code>NS_GET_IID()</code> to obtain the IID which is associated with that interface.</p>
+
+<pre>// returns a reference to a shared nsIID object\
+static const nsIID iid1 = NS_GET_IID(nsISupports);
+
+// constructs a new nsIID object
+static const nsIID iid2 = NS_ISUPPORTS_IID;
+</pre>
+
+<p>In order to use <code>NS_IMPL_ISUPPORTSn</code>, you must be sure that a member variable of type <code>nsrefcnt</code> is defined and named <code>mRefCnt</code> in your class. But why even bother when you can use another macro?</p>
+
+<h4 id="Declaration_Macros" name="Declaration_Macros">Declaration Macros</h4>
+
+<p><code>NS_DECL_NSISUPPORTS</code> declares <code>AddRef</code>, <code>Release</code>, and <code>QueryInterface</code> for you, and it also defines the <code>mRefCnt</code> required by <code>NS_IMPL_ISUPPORTS</code>. Furthermore, <code>NS_DECL_</code> appended with any interface name in all caps will declare all of the methods of that interface for you. For example, <code>NS_DECL_NSIFOO</code> will declare all of the methods of <code>nsIFoo</code> provided that it exists and that <code>nsIFoo.h</code> was generated by the XPIDL compiler. Consider the following real class:</p>
+
+<pre>class myEnumerator : public nsISimpleEnumerator
+{
+ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSISIMPLEENUMERATOR
+
+ myEnumerator();
+ virtual ~myEnumerator() {}
+};
+</pre>
+
+<p>The declaration of this <code>nsISimpleEnumerator</code> class doesn't include any methods other than the contructor and destructor. Instead, the class uses the <code>NS_DECL_</code> macro<sup><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Guide/Creating_components/Using_XPCOM_Utilities_to_Make_Things_Easier#endnote_nsISupports-warning">[nsISupports-warning]</a></sup>.</p>
+
+<p>Using these declaration macros not only saves a tremendous amount of time when you're writing the code, it can also save time if you make changes to your IDL file, since the C++ header file will then automatically include the updated list of methods to be supported.</p>
+
+<div class="side-note">
+<p>The <code>NS_INIT_ISUPPORTS</code> macro is also a bit of a special case. Historically, it gets called in the constructor for your class and sets <code>mRefCnt</code> to zero. However, a change in XPCOM that occurred before Mozilla 1.3 makes <code>NS_INIT_ISUPPORTS</code> no longer necessary: <code>mRefCnt</code>'s type has been changed from an integer to a class that provides its own auto-initialization. If you are building with versions earlier than Mozilla 1.3, this macro is still required.</p>
+</div>
+
+<p>The following table summarizes the macro usage in this portion of the <code>weblock.cpp</code> source file:</p>
+
+<p><span id="Common_XPCOM_Macros"><a id="Common_XPCOM_Macros"></a><strong>Common XPCOM Macros</strong></span></p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>NS_IMPL_ISUPPORTSn</code></td>
+ <td>Implements <code>nsISupports</code> for a given class with <code>n</code> number of interfaces</td>
+ </tr>
+ <tr>
+ <td><code>NS_DECL_ISUPPORTS</code></td>
+ <td>Declares methods of <code>nsISupports</code> including <code>mRefCnt</code></td>
+ </tr>
+ <tr>
+ <td><code>NS_INIT_ISUPPORTS</code></td>
+ <td>Initializes <code>mRefCnt</code> to zero. Must be called in class's constructor</td>
+ </tr>
+ <tr>
+ <td><code>NS_GET_IID</code></td>
+ <td>Returns the IID given the name of an interface. Interface must be generated by XPIDL</td>
+ </tr>
+ </tbody>
+</table>
+
+<p>Using the macros described here, the code for the <strong>WebLock</strong> component has gone from around 340 lines of code to just under 40. Clearly from a code maintenance point of view, this kind of reduction is outstanding. The entire source file with these macros included appears in <a href="#weblock2.cpp">weblock2.cpp</a>.</p>
+
+<h3 id="weblock2.cpp" name="weblock2.cpp">weblock2.cpp</h3>
+
+<p>The listing below shows the generic module code from <a href="cn/Creating_XPCOM_Components/Creating_the_Component_Code#webLock1.cpp">webLock1.cpp</a> using the macros described in this chapter:</p>
+
+<p><span id="weblock2.cpp"><a id="weblock2.cpp"></a><strong>weblock2.cpp</strong></span></p>
+
+<pre>#include "nsIGenericFactory.h"
+#include "nsISupportsUtils.h"
+
+#define SAMPLE_CID \
+{ 0x777f7150, 0x4a2b, 0x4301, \
+{ 0xad, 0x10, 0x5e, 0xab, 0x25, 0xb3, 0x22, 0xaa}}
+
+class Sample: public nsISupports
+{
+ public:
+ Sample();
+ virtual ~Sample();
+
+ NS_DECL_ISUPPORTS
+};
+
+Sample::Sample()
+{
+ // note: in newer versions of Gecko (1.3 or later)
+ // you don't have to do this:
+ NS_INIT_ISUPPORTS();
+}
+
+Sample::~Sample()
+{
+}
+
+NS_IMPL_ISUPPORTS1(Sample, nsISupports);
+
+NS_GENERIC_FACTORY_CONSTRUCTOR(Sample);
+
+static const nsModuleComponentInfo components[] =
+{
+ { "Pretty Class Name",
+ SAMPLE_CID,
+ "@company.com/sample",
+ SampleConstructor
+ }
+};
+
+NS_IMPL_NSGETMODULE(nsSampleModule, components)
+</pre>
+
+<h3 id="String_Classes_in_XPCOM" name="String_Classes_in_XPCOM">String Classes in XPCOM</h3>
+
+<p>Strings are usually thought of as linear sequences of characters. In C++, the string literal "XPCOM", for example, consists of 6 consecutive bytes, where `X' is at byte offset zero and a null character is at byte offset 5. Other kinds of strings like "wide" strings use two bytes to represent each character, and are often used to deal with Unicode strings.</p>
+
+<p>The string classes in XPCOM are not just limited to representing a null terminated sequence of characters, however. They are fairly complex because they support the Gecko layout engine and other subsystems that manage large chunks of data. Additionally, in some versions of Mozilla the string classes support sequences of characters broken up into multiple fragments (fragments which may or may not be null terminated)<sup><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Guide/Creating_components/Using_XPCOM_Utilities_to_Make_Things_Easier#endnote_nulls-in-strings">[nulls-in-strings]</a></sup>.</p>
+
+<p>All string classes in XPCOM derive from one of two abstract classes<sup><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Guide/Creating_components/Using_XPCOM_Utilities_to_Make_Things_Easier#endnote_other-string-classes">[other-string-classes]</a></sup>: <code>nsAString</code> and <code>nsACString</code>. The former handles double byte characters, and the latter tends to be used in more general circumstances, but both of these classes define the functionality of a string. You can see these classes being passed as arguments in many of the XPCOM interfaces we'll look at in the following chapters.</p>
+
+<h4 id="Using_Strings" name="Using_Strings">Using Strings</h4>
+
+<p>Explaining how all the string classes work is outside the scope of this book, but we can show you how to use strings in the <strong>WebLock</strong> component. The first thing to note is that the string classes themselves are not frozen, which means that you should not link against them when you can avoid it.</p>
+
+<p>Linking the full string library (<code>.lib</code> or <code>.a</code>) into a component may raise its footprint by more than 100k (on Windows), which in many cases is an unacceptable gain (see the <a href="cn/XPCOM_string_guide">XPCOM string guide</a>). For <strong>WebLock</strong>, where the string classes need to be only wrappers around already existing string data, trading advanced functionality for a much smaller footprint is the right way to go. The <strong>WebLock</strong> string classes don't need to append, concatenate, search, or do any other real work on the string data; they just need to represent <code>char*</code> and other data and pass them to methods that expect an <code>nsACString</code>.</p>
+
+<h4 id="nsEmbedString_and_nsEmbedCString" name="nsEmbedString_and_nsEmbedCString"><code>nsEmbedString</code> and <code>nsEmbedCString</code></h4>
+
+<p>The strings used in this tutorial are <code>nsEmbedString</code> and <code>nsEmbedCString</code>, which implement the <code>nsAString</code> abstract class and the <code>nsACString</code> abstract classes, respectively. This first example shows an <code>nsEmbedCString</code> being used to pass an <code>nsACString</code> to a method that's not expected to modify the string.</p>
+
+<pre>// in IDL: method(in ACString thing);
+
+char* str = "How now brown cow?";
+nsEmbedCString data(str);
+rv = object-&gt;Method(data);
+</pre>
+
+<p>In this next example, the method is going to set the value of the string - as it might need to do when it returns the name of the current user or the last viewed URL.</p>
+
+<pre>// in IDL: attribute ACString data;
+
+nsEmbedCString data;
+method-&gt;GetData(data);
+
+// now to extract the data from the url class:
+
+const char* aStringURL = data.get();
+</pre>
+
+<p>Note that the memory pointed to by <code>aStringURL</code> after the call to <code>url.get()</code> is owned by the URL string object. If you need to keep this string data around past the lifetime of the string object, you must make a copy.</p>
+
+<div class="side-note">
+<p><span id="String_Size"><a id="String_Size"></a><strong>String Size</strong></span></p>
+
+<p>The examples above illustrate the use of the single byte string class, <code>nsEmbedCString</code>. The double byte version, <code>nsEmbedString</code>, has the same functionality but the constructor takes <code>nsAString</code> and the .get() method returns the type <code>PRUnichar*</code>. Note that <code>PRUnichar</code> is a two byte value. In the coming chapters, you'll see examples that use this version in the <strong>WebLock</strong> component.</p>
+</div>
+
+<h3 id="Smart_Pointers" name="Smart_Pointers">Smart Pointers</h3>
+
+<p>All of the interfaces that you've seen so far are reference counted. Leaking a reference by not releasing an object, as the code below demonstrates, can be a major problem.</p>
+
+<pre>{
+ nsISupports* value = nsnull;
+ object-&gt;method(&amp;value);
+ if (!value) return;
+
+ // ...
+
+ if (NS_FAILED(error))
+ return; // &lt;------------ leaks |value|
+ //...
+
+ NS_RELEASE(value); // release our reference
+}
+</pre>
+
+<p>A method returns an <code>nsISupports</code> interface pointer that has been reference counted before it is returned (assuming it wasn't <code>nsnull</code>). If you handle an error condition by returning prematurely, whatever value points at will leak-it will never be deleted. This is a trivial fix in this example, but in real code, this can easily happen in <code>goto</code> constructs, or in deep nesting with early <code>return</code>s.</p>
+
+<p>Having more than one interface pointer that needs to be released when a block goes out of scope begs for a tool that can aid the developer. In XPCOM, this tool is the <code>nsCOMPtr</code>, or<em>smart pointer</em> class, which can save you countless hours and simplify your code when you're dealing with interface pointers. Using smart pointers, the code above can be simplified to:</p>
+
+<pre>{
+ nsCOMPtr&lt;nsISupports&gt; value;
+ object-&gt;method(getter_AddRefs(value));
+ if (!value) return;
+
+ // ...
+
+ if (NS_FAILED(error))
+ return;
+ // ...
+}
+</pre>
+
+<p>The style or syntax may be unfamilar, but smart pointers are worth learning and using because they simplify the task of managing references. <code>nsCOMPtr</code> is a C++ template class that acts almost exactly like raw pointers, that can be compared and tested, and so on. When you pass them to a getter, you must do something special, however: You must wrap the variable with the function <code>getter_AddRefs</code>, as in the example above.</p>
+
+<p>You cannot call the <code>nsISupports</code> <code>AddRef</code> or <code>Release</code> methods on a <code>nsCOMPtr</code>. But this restriction is desirable, since the <code>nsCOMPtr</code> is handling reference counting for you. If for some reason you need to adjust the reference count, you must assign the <code>nsCOMPtr</code> to a new variable and <code>AddRef</code> that. This is a common pattern when you have a local <code>nsCOMPtr</code> in a function and you must pass back a reference to it, as in the following:</p>
+
+<pre>SomeClass::Get(nsISupports** aResult)
+{
+ if (!aResult)
+ return NS_ERROR_NULL_POINTER;
+
+ nsCOMPtr&lt;nsISupports&gt; value;
+ object-&gt;method(getter_AddRefs(value));
+
+ *aResult = value.get();
+ NS_IF_ADDREF(*aResult);
+ return NS_OK;
+}
+</pre>
+
+<p>The first thing that this method does is check to see that the caller passed a valid address. If not, it doesn't even try to continue. Next, it calls another method on an object that is presumed to exist in this context. You can call a <code>.get()</code> method on the <code>nsCOMPtr</code> and have it returned for use as a raw pointer. This raw pointer can then be assigned to a variable and have its reference updated by <code>NS_IF_ADDREF</code>. Be very careful with the result of <code>.get()</code>, however. You should never call <code>Release</code> on this result because it may result in a crash. Instead, to explicitly release the object being held by a <code>nsCOMPtr</code>, you can assign zero to that pointer.</p>
+
+<p>Another nice feature of smart pointers - the part that makes them smart - is that you can <code>QueryInterface</code> them quite easily. For example, there are two interfaces for representing a file on a file system, the <code>nsIFile</code> and <code>nsILocalFile</code>, and they are both implemented by an object. Although we haven't formally introduced these two interfaces, the next code sample shows how simple it is to switch between these two interface:</p>
+
+<pre>SomeClass::DoSomething(nsIFile* aFile)
+{
+ if (!aFile)
+ return NS_ERROR_NULL_POINTER;
+
+ nsresult rv;
+ nsCOMPtr&lt;nsILocalFile&gt; localFile = do_QueryInterface(aFile, &amp;rv);
+ // ...
+}
+</pre>
+
+<p>If the <code>QueryInterface</code> is successful, <code>localFile</code> will be non-null, and <code>rv</code> will be set to <code>NS_OK</code>. If <code>QueryInterface</code> fails, <code>localFile</code> will be null, and <code>rv</code> will be set to a specific error code corresponding to the reason for the failure. In this construct, the result code <code>rv</code> is an optional parameter. If you don't care what the error code is, you can simply drop it from the function call.</p>
+
+<p>From this point on, we'll be using <code>nsCOMPtr</code>s as much as possible in <strong>WebLock</strong>. For a complete listing of smart pointer functionality, see <a class="external" href="http://www.mozilla.org/projects/xpcom/nsCOMPtr/">mozilla.org's <code>nsCOMPtr</code> documentation</a><span class="comment">XXX this should be in devmo</span>.</p>
+
+<ol>
+ <li><div class="blockIndicator note"><strong>Note:</strong> other-parts</div> This section discusses the main parameters of this structure. For a complete listing of all available options you can look at the complete reference in the <a href="cn/XPCOM_API_Reference">XPCOM API Reference</a>.</li>
+ <li><div class="blockIndicator note"><strong>Note:</strong> nsISupports-warning</div> Note that <code>NS_DECL_ISUPPORTS</code> doesn't obey the general rule in which every interface has a declaration macro of the form <code>NS_DECL_INTERFACENAME</code>, where <code>INTERFACENAME</code> is the name of the interface being compiled.</li>
+ <li><div class="blockIndicator note"><strong>Note:</strong> nulls-in-strings</div> The string classes may also support embedded nulls.</li>
+ <li><div class="blockIndicator note"><strong>Note:</strong> other-string-classes</div> There are other abstract string classes, but they are outside the scope of this book.</li>
+</ol>
+
+<p></p><div class="prevnext" style="text-align: right;">
+ <p><a href="/zh-CN/docs/Creating_XPCOM_Components:Creating_the_Component_Code" style="float: left;">« 上一页</a><a href="/zh-CN/docs/Creating_XPCOM_Components:Starting_WebLock">下一页 »</a></p>
+</div> <p></p><div class="licenseblock">
+<p>Copyright (c) 2003 by Doug Turner and Ian Oeschger. This material may be distributed only subject to the terms and conditions set forth in the <a class="external" href="http://www.opencontent.org/openpub/" rel="noopener">Open Publication License</a>, v1.02 or later. Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.</p>
+</div><p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/hashtables/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/hashtables/index.html
new file mode 100644
index 0000000000..24740b535c
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/guide/hashtables/index.html
@@ -0,0 +1,282 @@
+---
+title: Hashtables
+slug: Mozilla/Tech/XPCOM/Guide/Hashtables
+tags:
+ - XPCOM
+ - 所有分类
+translation_of: Mozilla/Tech/XPCOM/Guide/Hashtables
+---
+<p> </p>
+<h2 id="What_Is_a_Hashtable.3F" name="What_Is_a_Hashtable.3F">What Is a Hashtable?</h2>
+<p>A hashtable is a data construct that stores a set of <b>items</b>. Each item has a <b>key</b> that identifies the item. Items are found, added, and removed from the hashtable by using the key. Hashtables may seem like <a href="cn/XPCOM_array_guide">arrays</a>, but there are important differences:</p>
+<p>哈希表是一个存储一系列<b>元素</b>的数据结构。每个元素都由一个<b>关键字</b>来标识。元素可以通过关键字来进行查找,添加,删除操作。哈希表非常类似<a href="cn/XPCOM_array_guide">arrays</a>,但是也有一些很大的区别。</p>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th> </th>
+ <th class="header">数组</th>
+ <th class="header">哈希表</th>
+ </tr>
+ <tr>
+ <td class="header">关键字:</td>
+ <td>
+ <i>
+ 整数:</i>
+ arrays are always keyed on integers, and must be contiguous. 数组必须用整数作为关键字,而且每两个元素之间必须相邻接</td>
+ <td>
+ <i>
+ 任意类型:</i>
+ almost any datatype can be used as key, including strings, integers, XPCOM interface pointers, IIDs, and almost anything else. Keys can be disjunct (i.e. you can store entries with keys 1, 5, and 3000). 任意类型都可以作为关键字,包括字符串,整数,XPCOM接口指针,IIDs等等。关键字之间可以不在一起(例如,你可以用1,5,和3000来作为关键字。)</td>
+ </tr>
+ <tr>
+ <td class="header">查询时间:</td>
+ <td>
+ <i>
+ O(1):</i>
+ lookup time is a simple constant。查找时间是个简单的定值</td>
+ <td>
+ <i>
+ O(1):</i>
+ lookup time is mostly-constant, but the constant time can be larger than an array lookup。查找时间几乎是定值,但是比数组慢点。</td>
+ </tr>
+ <tr>
+ <td class="header">排序:</td>
+ <td>
+ <i>
+ sorted:</i>
+ stored sorted; enumerated in a sorted fashion.</td>
+ <td>
+ <i>
+ unsorted:</i>
+ stored unsorted; cannot be enumerated in a sorted manner.</td>
+ </tr>
+ <tr>
+ <td class="header">插入/删除:</td>
+ <td>
+ <i>
+ O(n):</i>
+ adding and removing items from a large array can be time-consuming</td>
+ <td>
+ <i>
+ O(1):</i>
+ adding and removing items from hashtables is a quick operation</td>
+ </tr>
+ <tr>
+ <td class="header">浪费空间:</td>
+ <td>
+ <i>
+ none:</i>
+ Arrays are packed structures, so there is no wasted space.</td>
+ <td>
+ <i>
+ some:</i>
+ hashtables are not packed structures; depending on the implementation, there may be significant wasted memory.</td>
+ </tr>
+ </tbody>
+</table>
+<p>In their implementation, hashtables take the key and apply a mathematical <b>hash function</b> to <b>randomize</b> the key and then use the hash to find the location in the hashtable. Good hashtable implementations will automatically resize the hashtable in memory if extra space is needed, or if too much space has been allocated.</p>
+<h2 id="When_Should_I_Use_a_Hashtable.3F" name="When_Should_I_Use_a_Hashtable.3F">When Should I Use a Hashtable?</h2>
+<p>Hashtables are useful for</p>
+<ul>
+ <li>sets of data that need swift <b>random access</b>;</li>
+ <li>with <b>non-integral keys</b> or <b>non-contiguous integral keys</b>;</li>
+ <li>or where <b>items will be frequently added or removed</b>.</li>
+</ul>
+<p>Hashtables should
+ <i>
+ not</i>
+ be used for</p>
+<ul>
+ <li>Sets that need to be <b>sorted</b>;</li>
+ <li>Very small datasets (less than 12-16 items);</li>
+ <li>Data that does not need random access.</li>
+</ul>
+<p>In these situations, an array, a linked-list, or various tree data structures are more efficient.</p>
+<h2 id="Mozilla.27s_Hashtable_Implementations" name="Mozilla.27s_Hashtable_Implementations">Mozilla's Hashtable Implementations</h2>
+<p>Mozilla has several hashtable implementations, which have been tested and, tuned, and hide the inner complexities of hashtable implementations:</p>
+<ul>
+ <li><code><a href="#PLDHash_.28JSDHash.29">PLDHash</a></code> - low-level C API; stores keys and data in one large memory structure; uses the heap efficiently; client must declare an "entry class" and may not hold onto entry pointers.</li>
+ <li><code><a href="#PLHashTable">PLHashTable</a></code> - low-level C API; entry class pointers are constant; more efficient for large entry structures; often wastes memory making many small heap allocations.</li>
+ <li><code><a href="#nsTHashtable">nsTHashtable</a></code> - low-level C++ wrapper around <code>PLDHash</code>; generates callback functions and handles most casting automagically. Client writes their own entry class which can include complex key and data types.</li>
+ <li><code><a href="#nsBaseHashtable_and_friends:_nsDataHashtable.2C_nsInterfaceHashtable.2C_and_nsClassHashtable">nsDataHashtable/nsInterfaceHashtable/nsClassHashtable</a></code> - high-level C++ wrappers around <code>PLDHash</code>; simplifies the common usage pattern mapping a simple keytype to a simple datatype; client does not need to declare or manage an entry class; <code><b>nsDataHashtable</b></code> datatype is a scalar such as <code>RUint32</code>; <code><b>nsInterfaceHashtable</b></code> datatype is an interface; <code><b>nsClassHashtable</b></code> datatype is a class pointer owned by the hashtable.</li>
+</ul>
+<h3 id="Which_Hashtable_Should_I_Use.3F" name="Which_Hashtable_Should_I_Use.3F">Which Hashtable Should I Use?</h3>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th class="header" colspan="2" rowspan="2"> </th>
+ <th class="header" colspan="5">Key Type:</th>
+ </tr>
+ <tr>
+ <th class="header">integer</th>
+ <th class="header">String/CString</th>
+ <th class="header">nsID</th>
+ <th class="header">nsISupports*</th>
+ <th class="header">Complex</th>
+ </tr>
+ <tr>
+ <td class="header" rowspan="8">Data Type:</td>
+ <td class="header">None (Hash Set)</td>
+ <td><code>nsInt32HashSet</code></td>
+ <td><code>ns(C)StringHashSet</code></td>
+ <td colspan="3"><code>nsTHashtable&lt;...&gt;</code></td>
+ </tr>
+ <tr>
+ <td class="header" rowspan="2">Simple (PRUint32)</td>
+ <td colspan="4"><code>nsDataHashtable</code></td>
+ <td rowspan="6"><code>nsTHashtable&lt;...&gt;</code></td>
+ </tr>
+ <tr>
+ <td><code>&lt;nsUint32HashKey,<br>
+ PRUint32&gt;</code></td>
+ <td><code>&lt;ns(C)StringHashKey,<br>
+ PRUint32&gt;</code></td>
+ <td><code>&lt;nsIDHashKey,<br>
+ PRUint32&gt;</code></td>
+ <td><code>&lt;nsISupportsHashKey,<br>
+ PRUint32&gt;</code></td>
+ </tr>
+ <tr>
+ <td class="header" rowspan="2">Interface (nsISupports)</td>
+ <td colspan="4"><code>nsInterfaceHashtable</code></td>
+ </tr>
+ <tr>
+ <td><code>&lt;nsUint32HashKey,<br>
+ nsISupports&gt;</code></td>
+ <td><code>&lt;ns(C)StringHashKey,<br>
+ nsISupports&gt;</code></td>
+ <td><code>&lt;nsIDHashKey,<br>
+ nsISupports&gt;</code></td>
+ <td><code>&lt;nsISupportsHashKey,<br>
+ nsISupports&gt;</code></td>
+ </tr>
+ <tr>
+ <td class="header" rowspan="2">Class (nsString*)</td>
+ <td colspan="4"><code>nsClassHashtable</code></td>
+ </tr>
+ <tr>
+ <td><code>&lt;nsUint32HashKey,<br>
+ nsString&gt;</code></td>
+ <td><code>&lt;ns(C)StringHashKey,<br>
+ nsString&gt;</code></td>
+ <td><code>&lt;nsIDHashKey,<br>
+ nsString&gt;</code></td>
+ <td><code>&lt;nsISupportsHashKey,<br>
+ nsString&gt;</code></td>
+ </tr>
+ <tr>
+ <td class="header">Complex<br>
+ (structures, etc.)</td>
+ <td colspan="5"><code>nsTHashtable&lt;...&gt;</code></td>
+ </tr>
+ </tbody>
+</table>
+<h3 id="PLDHash_.28JSDHash.29" name="PLDHash_.28JSDHash.29">PLDHash (JSDHash)</h3>
+<p><code>PLDHash</code> and <code>JSDHash</code> are the same thing; one is linked from the XPCOM libraries, the other from the JS libraries. <code>JSDHash</code> is used extensively in the SpiderMonkey JS engine.</p>
+<p>The <code>PLDHash</code> implementation is a fairly low-level implementation, written in C. It is extremely flexible, but requires some time to understand and use. A basic guide is included here, but you should read most of <code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/glue/pldhash.h" rel="custom">xpcom/glue/pldhash.h</a></code> if you intend to use <code>PLDHash</code>. The C++ wrappers for <code>PLDHash</code> (see below) are often much easier and safer to use in C++ code, as many potential casting errors are easily avoided.</p>
+<p>You must declare an <b>entry struct</b> type, deriving from <a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/glue/pldhash.h#81" rel="custom">&lt;code&gt;PLDHashEntryHdr&lt;/code&gt;</a>. This entry struct should contain whatever data you wish to store in the hashtable (any pointer or fixed-length data type). <b>Note:</b> because of the double-hashing implementation, entries may move in memory when the hashtable is altered. If you need entry pointers to remain constant, you may want to consider using <code><a href="#PLHashTable">PLHashTable</a></code> instead.</p>
+<p>You must also initialize a <a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/glue/pldhash.h#312" rel="custom">&lt;code&gt;PLDHashTableOps&lt;/code&gt;</a> structure. This serves similarly to a vtable in C++, with pointers to appropriate user-defined functions that initialize, compare, and match entries. Because <code>PLDHash</code> does not know what datatype your key is, all functions that work with keys are declared using <code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/glue/pldhash.h#354" rel="custom">const void*</a></code>, and your client code must cast these pointers to the appropriate type.</p>
+<p>PLDHashTables can be allocated on the stack or the heap:</p>
+<ul>
+ <li>When allocated on the stack, or as a C++ class member, the table must be initialized using <code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/glue/pldhash.h#427" rel="custom">PL_DHashTableInit</a></code>, and finalized using <code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/glue/pldhash.h#459" rel="custom">PL_DHashTableFinish</a></code>;</li>
+ <li>When allocated on the heap, use <code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/glue/pldhash.h#410" rel="custom">PL_NewDHashTable</a></code> and <code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/glue/pldhash.h#420" rel="custom">PL_DHashTableDestroy</a></code> to allocate and delete the table.</li>
+</ul>
+<h3 id="PLHashTable" name="PLHashTable">PLHashTable</h3>
+<p><code>PLHashTable</code> is a part of NSPR. The header file can be found at <code><code><a href="https://dxr.mozilla.org/mozilla-central/source/nsprpub/lib/ds/plhash.h" rel="custom">nsprpub/lib/ds/plhash.h</a></code></code>. In general, <code><a href="#PLDHash_.28JSDHash.29">PLDHash</a></code> is a better solution than <code>PLHashTable</code>, because <code>PLHashTable</code> makes many heap allocations.</p>
+<p>There are two situations where <code>PLHashTable</code> may be preferable to <code>PLDHash</code>:</p>
+<ul>
+ <li>You need entry-pointers to remain constant.</li>
+ <li>The entries stored in the table are very large (larger than 12 words). <code>PLDHash</code> does not handle large entry structures efficiently.</li>
+</ul>
+<h3 id="nsTHashtable" name="nsTHashtable">nsTHashtable</h3>
+<p><code>nsTHashtable</code> is a C++ template that wraps <code>PLDHash</code>. It hides many of the complexities of <code>PLDHash</code> (callback functions, the ops structure, etc). You should read <code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/glue/nsTHashtable.h" rel="custom">xpcom/glue/nsTHashtable.h</a></code>.</p>
+<p>To use <code>nsTHashtable</code>, you must declare an entry-class in a <a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/glue/nsTHashtable.h#65" rel="custom">pre-defined format</a>. This entry class contains the key and the data that you are hashing (just like <code>PLDHash</code>, above). It also declares functions that manipulate the key. In most cases, the functions of this entry class can be entirely inline. For examples of entry classes, see the declarations at <code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/glue/nsHashKeys.h" rel="custom">xpcom/glue/nsHashKeys.h</a></code>.</p>
+<p>The template parameter is the entry class. You must use the <code>Init()</code> function to initalize the table properly. At this point, use the functions <code>PutEntry/GetEntry/RemoveEntry</code> to alter the hashtable. <code>EnumerateEntries</code> will do enumeration, but beware that the enumeration will occur in a seemingly-random order (no sorting).</p>
+<ul>
+ <li><code>nsTHashtable</code>s can be allocated on the stack, as class members, or on the heap.</li>
+ <li>Entry pointers can and do change when items are added to the hashtable, or removed. Do not keep long-lasting pointers to entries.</li>
+ <li>because of this, <code>nsTHashtable</code> is not inherently thread-safe. If you use a hashtable in a multi-thread environment, you must provide locking as appropriate.</li>
+</ul>
+<p>Before using <code>nsTHashtable</code>, see if <code>nsBaseHashtable</code> and relatives will work for you. They are much easier to use, because you do not have to declare an entry class. If you are hashing a simple key type to a simple data type, they are generally a better choice.</p>
+<h3 id="nsBaseHashtable_and_friends:_nsDataHashtable.2C_nsInterfaceHashtable.2C_and_nsClassHashtable" name="nsBaseHashtable_and_friends:_nsDataHashtable.2C_nsInterfaceHashtable.2C_and_nsClassHashtable">nsBaseHashtable and friends: nsDataHashtable, nsInterfaceHashtable, and nsClassHashtable</h3>
+<p>These C++ templates provide a high-level interface for using hashtables that hides most of the complexities of <code>PLDHash</code>. They provide the following features:</p>
+<ul>
+ <li>hashtable operations can be completed without using an entry class, making code easier to read;</li>
+ <li>optional thread-safety: the hashtable can manage a read-write lock around the table;</li>
+ <li>predefined key classes provide automatic cleanup of strings/interfaces</li>
+ <li><code>nsInterfaceHashtable</code> and <code>nsClassHashtable</code> automatically release/delete data pointers to avoid leaks.</li>
+</ul>
+<p><code>nsBaseHashtable</code> is not used directly; choose one of the three derivative classes based on the data type you want to store. The <code>KeyClass</code> is taken from <code>nsHashKeys.h</code> and is the same for all three classes:</p>
+<ul>
+ <li><code>nsDataHashtable&lt;KeyClass,
+ <i>
+ DataType</i>
+ &gt;</code> - <code>DataType</code> is a simple type such as <code>PRUint32</code> or <code>PRBool</code>.</li>
+ <li><code>nsInterfaceHashtable&lt;KeyClass,
+ <i>
+ Interface</i>
+ &gt;</code> - <code>Interface</code> is an XPCOM interface such as <code>nsISupports</code> or <code>nsIDOMNode</code></li>
+ <li><code>nsClassHashtable&lt;KeyClass,
+ <i>
+ T</i>
+ &gt;</code> - <code>T</code> is any C++ class. The hashtable stores a pointer to the class, and deletes it when the entry is removed.</li>
+</ul>
+<p>The important files to read are <code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/glue/nsBaseHashtable.h" rel="custom">xpcom/glue/nsBaseHashtable.h</a></code> and <code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/glue/nsHashKeys.h" rel="custom">xpcom/glue/nsHashKeys.h</a></code>. These classes can be used on the stack, as a class member, or on the heap. Initialize using the <code>Init()</code> function; you can specify whether you need thread-safety at this time. Use the <code>Put()</code>, <code>Get()</code>, and <code>Remove()</code> methods to alter the table.</p>
+<p>There are two enumeration functions:</p>
+<ul>
+ <li><code>EnumerateRead()</code> performs a read-only enumeration, where entries cannot be changed or removed;</li>
+ <li><code>Enumerate()</code> performs a read-write enumeration, where entries may be changed or removed as necessary.</li>
+</ul>
+<h3 id="Using_nsTHashtable_as_a_hash-set" name="Using_nsTHashtable_as_a_hash-set">Using nsTHashtable as a hash-set</h3>
+<p>A hash set only tracks the existence of keys: it does not associate data with the keys. This can be done using <code>nsTHashtable&lt;nsSomeHashKey&gt;</code>. The appropriate entries are GetEntry and PutEntry.</p>
+<h2 id="Future_Plans" name="Future_Plans">Future Plans</h2>
+<h3 id="nsISimpleEnumerator_support" name="nsISimpleEnumerator_support">nsISimpleEnumerator support</h3>
+<p>The (obsolete) <code>nsHashtable</code> has a wrapper that exposes an <code>nsISimpleEnumerator</code> on its items. I will add this support to the various <code>nsBaseHashtable</code> classes as well, as needed.</p>
+<h2 id="Hash_Functions" name="Hash_Functions">Hash Functions</h2>
+<p>All of the above hashtables need a <a class="external" href="http://www.nist.gov/dads/HTML/hash.html">Hash Function</a>. This function converts the key into a semi-unique integer. The mozilla codebase already contains hash functions for most key types, including narrow and wide strings, pointers, and most binary data:</p>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>void*<br>
+ (or nsISupports*)</code></td>
+ <td>cast using <code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/base/nscore.h#443" rel="custom">NS_PTR_TO_INT32</a></code></td>
+ </tr>
+ <tr>
+ <td><code>char*</code> string</td>
+ <td rowspan="2"><code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/ds/nsCRT.h#228" rel="custom">nsCRT::HashCode()</a></code></td>
+ </tr>
+ <tr>
+ <td><code>PRUnichar*</code> string</td>
+ </tr>
+ <tr>
+ <td><code>nsAString</code></td>
+ <td rowspan="2"><code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/glue/nsTHashtable.cpp#41" rel="custom">HashString()</a></code></td>
+ </tr>
+ <tr>
+ <td><code>nsACString</code></td>
+ </tr>
+ <tr>
+ <td><code>nsID&amp;</code></td>
+ <td><code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/glue/nsHashKeys.h#227" rel="custom">nsIDHashKey::HashKey()</a></code></td>
+ </tr>
+ </tbody>
+</table>
+<p>Writing a good hash function is well beyond the scope of this document, and has been discussed extensively in computer-science circles for many years. There are many different types of hash functions. Mozilla has tuned a good general-purpose hash algorithm for strings and <code>nsID</code>.</p>
+<h2 id="Mozilla.27s_Old.2FObsolete.2FDeprecated.2FDecrepit_Hashtables" name="Mozilla.27s_Old.2FObsolete.2FDeprecated.2FDecrepit_Hashtables">Mozilla's Old/Obsolete/Deprecated/Decrepit Hashtables</h2>
+<h3 id="nsHashtable" name="nsHashtable">nsHashtable</h3>
+<p><code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/ds/nsHashtable.h" rel="custom">nsHashtable</a></code> was a C++ wrapper around <code>PLHashTable</code>, and now wraps <code>PLDHash</code>. The design of the key classes is not optimal, however, and <code>nsHashtable</code> has been deprecated in favor of <code>nsDataHashtable</code> and friends.</p>
+<h3 id="nsObjectHashtable" name="nsObjectHashtable">nsObjectHashtable</h3>
+<p><code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/ds/nsHashtable.h#163" rel="custom">nsObjectHashtable</a></code> is a form of <code>nsHashtable</code>. It has been replaced by <code>nsClassHashtable</code>.</p>
+<h3 id="nsSupportsHashtable" name="nsSupportsHashtable">nsSupportsHashtable</h3>
+<p><code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/ds/nsHashtable.h#193" rel="custom">nsSupportsHashtable</a></code> is a form of <code>nsHashtable</code>. It has been replaced by <code>nsInterfaceHashtable</code>.</p>
+<h3 id="nsHashSets" name="nsHashSets">nsHashSets</h3>
+<p><code>nsHashSets</code> has predefined hash sets for common keys, which are trivially easy to use. See <code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/ds/nsHashSets.h" rel="custom">xpcom/ds/nsHashSets.h</a></code>. This functionality has been replaced by <code>nsTHashtable&lt;nsSomeHashKey&gt;</code>.</p>
+<h3 id="nsDoubleHashtable" name="nsDoubleHashtable">nsDoubleHashtable</h3>
+<p><code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/ds/nsDoubleHashtable.h" rel="custom">nsDoubleHashtable</a></code> is the (obsolete) precursor to <code>nsTHashtable</code>. It uses macros instead of C++ templates.</p>
+<div class="originaldocinfo">
+ <h2 id="Original_Document_Information" name="Original_Document_Information">Original Document Information</h2>
+ <ul>
+ <li>Author(s): Benjamin Smedberg &lt;<a class="link-mailto" href="mailto:benjamin@smedbergs.us" rel="freelink">benjamin@smedbergs.us</a>&gt;</li>
+ </ul>
+</div>
+<p> </p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/index.html
new file mode 100644
index 0000000000..385888d9fb
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/guide/index.html
@@ -0,0 +1,15 @@
+---
+title: XPCOM 指南
+slug: Mozilla/Tech/XPCOM/Guide
+tags:
+ - Landing
+ - Mozilla
+ - XPCOM
+translation_of: Mozilla/Tech/XPCOM/Guide
+---
+<p> </p>
+<p><span class="seoSummary" style="padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px;">本文提供了关于 XPCOM 的说明和使用文档,包括如何在你的工程中使用,如何为你的 Firefox 扩展等构建 XPCOM 组件。</span></p>
+<p></p><div class="row topicpage-table">
+ <div class="section"><dl><dl><dt class="landingPageList"><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Guide/Arrays">Array</a></dt><dd class="landingPageList"></dd><dt class="landingPageList"><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Guide/Hashtables">Hashtables</a></dt><dd class="landingPageList"></dd><dt class="landingPageList"><a href="/zh-CN/docs/How_to_Build_an_XPCOM_Component_in_Javascript">How to Build an XPCOM Component in Javascript</a></dt><dd class="landingPageList"></dd></dl></dl></div>
+ <div class="section"><dl><dt class="landingPageList"><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Guide/Internal_strings">Strings</a></dt><dd class="landingPageList"></dd><dt class="landingPageList"><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Guide/Creating_components">创建_XPCOM_组件</a></dt><dd class="landingPageList"></dd></dl></div>
+ </div><p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/guide/internal_strings/index.html b/files/zh-cn/mozilla/tech/xpcom/guide/internal_strings/index.html
new file mode 100644
index 0000000000..fe5806168f
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/guide/internal_strings/index.html
@@ -0,0 +1,809 @@
+---
+title: Strings
+slug: Mozilla/Tech/XPCOM/Guide/Internal_strings
+tags:
+ - XPCOM
+ - 所有分类
+translation_of: Mozilla/Tech/XPCOM/Guide/Internal_strings
+---
+<p> </p>
+<h2 id="Preface" name="Preface">Preface</h2>
+<div>
+ <p>by Alec Flett<br>
+ Thanks to David Baron for <a class="external" href="http://dbaron.org/mozilla/coding-practices">actual docs</a>,<br>
+ Peter Annema for lots of direction,<br>
+ Myk Melez for some more docs, and<br>
+ David Bradley for a diagram<br>
+ Revised by Darin Fisher for Mozilla 1.7<br>
+ Revised by Jungshik Shin to clarify character encoding issues</p>
+</div>
+<p>This guide will attempt to document the plethora of string classes, and hopefully provide an answer to the age old question, "what string class should I use here?"</p>
+<div style="border: solid thin steelblue; padding: 0.5em;">
+ <p>If you are a Mozilla embedder or if you are writing an XPCOM component that will be distributed separately from the Mozilla code base, then this string guide is most likely not for you! Provided you are developing against Mozilla 1.7 or later, you should instead be using the new minimal <a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/glue/nsStringAPI.h" rel="custom">Mozilla string API</a> and in particular the <a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/string/public/nsEmbedString.h" rel="custom">nsEmbedString</a> class.</p>
+</div>
+<p>In a hurry? Go check out the <a href="cn/XPCOM/String_Quick_Reference">String Quick-Reference</a> (<a class="external" href="http://www.mozilla.org/projects/xpcom/string-quickref.html">). </a></p>
+<h2 id="Introduction" name="Introduction"><a class="external" href="http://www.mozilla.org/projects/xpcom/string-quickref.html">Introduction </a></h2>
+<p><a class="external" href="http://www.mozilla.org/projects/xpcom/string-quickref.html">The string classes are a library of C++ classes which are used to manage buffers of unicode and single-byte character strings. They reside in the mozilla codebase in the <code></code></a><code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/string" rel="custom">xpcom/string</a></code> directory. </p>
+<p><a class="external" href="http://www.mozilla.org/projects/xpcom/string-quickref.html">Abstract (interface) classes begin with "nsA" and concrete classes simply begin with "ns". Classes with a "<code>CString</code>" in the name store 8-bit bytes (<code>char</code>'s) which may refer to single byte ASCII strings, or multibyte Unicode strings encoded in UTF-8 or a (multibyte or single byte) legacy character encoding (e.g. ISO-8859-1, Shift_JIS, GB2312, KOI8-R). All other classes simply have "<code>String</code>" in their name and refer to 16-bit strings made up of <code>PRUnichar</code>'s, For example: <code>nsAString</code> is an abstract class for storing Unicode characters in UTF-16 encoding, and <code>nsDependentCString</code> is a concrete class which stores a 8-bit string. Every 16-bit string class has an equivalent 8-bit string class. For example: <code>nsCString</code> is the 8-bit string class which corresponds to <code>nsString</code>. </a></p>
+<p><a class="external" href="http://www.mozilla.org/projects/xpcom/string-quickref.html">8-bit and 16-bit string classes have completely separate base classes, but share the same APIs. As a result, you cannot assign a 8-bit string to a 16-bit string without some kind of conversion helper class or routine. For the purpose of this document, we will refer to the 16-bit string classes in class documentation. It is safe to assume that every 16-bit class has an equivalent 8-bit class. </a></p>
+<h2 id="String_Guidelines" name="String_Guidelines"><a class="external" href="http://www.mozilla.org/projects/xpcom/string-quickref.html">String Guidelines </a></h2>
+<p><a class="external" href="http://www.mozilla.org/projects/xpcom/string-quickref.html">Follow these simple rules in your code to keep your fellow developers, reviewers, and users happy. </a></p>
+<ul>
+ <li><a class="external" href="http://www.mozilla.org/projects/xpcom/string-quickref.html">Avoid </a><code><a href="#Unicode_Conversion_ns.2ACString_vs._ns.2AString">*WithConversion</a></code> functions at all costs: <code>AssignWithConversion</code>, <code>AppendWithConversion</code>, <code>EqualsWithConversion</code>, etc</li>
+ <li>Use the most abstract string class that you can. Usually this is:
+ <ul>
+ <li><code><a href="#The_Abstract_Classes">nsAString</a></code> for function parameters</li>
+ <li><code><a href="#The_Concrete_Classes_-_which_classes_to_use_when">nsString</a></code> for member variables</li>
+ <li><a href="#The_Concrete_Classes_-_which_classes_to_use_when"><code>nsAutoString</code> or <code>nsXPIDLString</code></a> for local (stack-based) variables</li>
+ </ul>
+ </li>
+ <li>Use <a href="#Literal_Strings"><code>NS_LITERAL_[C]STRING</code> / <code>NS_NAMED_LITERAL_[C]STRING</code></a> to represent literal strings (i.e. "foo") as nsAString-compatible objects.</li>
+ <li>Use <a href="#String_Concatenation">string concatenation</a> (i.e. the "+" operator) when combining strings.</li>
+ <li>Use <code><a href="#Raw_Character_Pointers">nsDependentString</a></code> when you have a raw character pointer that you need to convert to an nsAString-compatible string.</li>
+ <li>Use <code><a href="#Substrings_.28string_fragments.29">Substring()</a></code> to extract fragments of existing strings.</li>
+ <li>Use <a href="#Iterators">iterators</a> to parse and extract string fragments.</li>
+</ul>
+<h2 id="The_Abstract_Classes" name="The_Abstract_Classes">The Abstract Classes</h2>
+<p>Every string class derives from <code>nsAString</code> (or <code>nsACString</code>). This class provides the fundamental interface for access and manipulation of strings. While concrete classes derive from <code>nsAString</code>, <code>nsAString</code> itself cannot be instantiated.</p>
+<p>This is very similar to the idea of an "interface" that mozilla uses to describe abstract object descriptions in the rest of the codebase. In the case of interfaces, class names begin with "nsI" where "I" refers to "Interface". In the case of strings, abstract classes begin with "nsA" and the "A" means "Abstract".</p>
+<p>There are a number of abstract classes which derive from <code>nsAString</code>. These abstract subclasses also cannot be instantiated, but they describe a string in slightly more detail than <code>nsAString</code>. They guarantee that the underlying implementation behind the abstract class provides specific capabilities above and beyond <code>nsAString</code>.</p>
+<p>The list below describes the main base classes. Once you are familiar with them, see the appendix describing What Class to Use When.</p>
+<ul>
+ <li><b><code>nsAString</code></b>: the abstract base class for all strings. It provides an API for assignment, individual character access, basic manipulation of characters in the string, and string comparison. This class corresponds to the XPIDL <code>AString</code> parameter type.</li>
+ <li><b><code>nsSubstring</code></b>: the common base class for all of the string classes. Provides optimized access to data within the string. A <code>nsSubstring</code> is not necessarily null-terminated. (For backwards compatibility, <code>nsASingleFragmentString</code> is a typedef for this string class.)</li>
+ <li><b><code>nsString</code></b>: builds on <code>nsSubstring</code> by guaranteeing a null-terminated storage. This allows for a method (<code>.get()</code>) to access the underlying character buffer. (For backwards compatibility, <code>nsAFlatString</code> is a typedef for this string class.)</li>
+</ul>
+<p>The remainder of the string classes inherit from either <code>nsSubstring</code> or <code>nsString</code>. Thus, every string class is compatible with <code>nsAString</code>.</p>
+<p>It's important to note that <code>nsSubstring</code> and <code>nsAString</code> both represent a contiguous array of characters that are not necessarily null-terminated. One might ask then ask why two different yet similar string classes need to exist. Well, <code>nsSubstring</code> exists primarily as an optimization since <code>nsAString</code> must retain binary compatibility with the frozen <code>nsAString</code> class that shipped with Mozilla 1.0. Up until the release of Mozilla 1.7, <code>nsAString</code> was capable of representing a string broken into multiple fragments. The cost associated with supporting multi-fragment strings was high and offered limited benefits. It was decided to eliminate support for multi-fragment strings in an effort to reduce the complexity of the string classes and improve performance. See <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=231995" title='FIXED: Exploring nsAString "defragmentation"'>bug 231995</a> for more details.</p>
+<p>Though <code>nsSubstring</code> provides a more efficient interface to its underlying buffer than <code>nsAString</code>, <code>nsAString</code> is still the most commonly used class for parameter passing. This is because it is the string class corresponding to <code>AString</code> in XPIDL. Therefore, this string guide will continue to discuss the string classes with an emphasis on <code>nsAString</code>.</p>
+<p>Since every string derives from <code>nsAString</code> (or <code>nsACString</code>), they all share a simple API. Common read-only methods:</p>
+<ul>
+ <li><b><code>.Length()</code></b> - the number of code units (bytes for 8-bit string classes and PRUnichar's for 16-bit string classes) in the string.</li>
+ <li><b><code>.IsEmpty()</code></b> - the fastest way of determining if the string has any value. Use this instead of testing <code>string.Length</code> == 0</li>
+ <li><b><code>.Equals(string)</code></b> - TRUE if the given string has the same value as the current string.</li>
+</ul>
+<p>Common methods that modify the string:</p>
+<ul>
+ <li><b><code>.Assign(string)</code></b> - Assigns a new value to the string.</li>
+ <li><b><code>.Append(string)</code></b> - Appends a value to the string.</li>
+ <li><b><code>.Insert(string, position)</code></b> - Inserts the given string before the code unit at position.</li>
+ <li><b><code>.Truncate(length)</code></b> - shortens the string to the given length.</li>
+</ul>
+<p>Complete documentation can be found in the <a href="#Appendix_B_-_nsAString_Reference">Appendix</a>.</p>
+<h3 id="Read-only_strings" name="Read-only_strings">Read-only strings</h3>
+<p>The <code>const</code> attribute on a string determines if the string is writable. If a string is defined as a <code>const nsAString</code> then the data in the string cannot be manipulated. If one tries to call a non-<code>const</code> method on a <code>const</code> string the compiler will flag this as an error at build time.</p>
+<p>For example:</p>
+<pre class="eval">void nsFoo::ReverseCharacters(nsAString&amp; str) {
+ ...
+ str.Assign(reversedStr); // modifies the string
+}
+</pre>
+<p>This should not compile, because you're assigning to a <code>const</code> class:</p>
+<pre class="eval">void nsFoo::ReverseCharacters(const nsAString&amp; str) {
+ ...
+ <b>str.Assign(reversedStr);</b>
+}
+</pre>
+<h3 id="As_function_parameters" name="As_function_parameters">As function parameters</h3>
+<p>It is recommended that you use the most abstract interface possible as a function parameter, instead of using concrete classes. The convention is to use C++ references (the '&amp;' character) instead of pointers (the '*' character) when passing string references around. For example:</p>
+<pre class="eval">// abstract reference
+nsFoo::PrintString(<b>const nsAString&amp;</b> str) {..}
+
+// using a concrete class!
+nsFoo::PrintString(<b>const nsString&amp;</b> str) {..}
+
+// using a pointer!
+nsFoo::PrintString(<b>const nsAString*</b> str) {..}
+</pre>
+<p>The abstract classes are also sometimes used to store temporary references to objects. You can see both of these uses in <a href="#Common_Patterns">Common Patterns</a>, below.</p>
+<p><b>NOTE:</b> While using abstract string classes increases the re-usability of your methods, it also incurs a codesize and performance penalty. Therefore, when writing methods that will only ever be used within the confines of your source file or module, it is better to use <b><code>const nsSubstring&amp;</code></b> for input parameters and <b><code>nsString&amp;</code></b> for output parameters. --Darin</p>
+<h2 id="The_Concrete_Classes_-_which_classes_to_use_when" name="The_Concrete_Classes_-_which_classes_to_use_when">The Concrete Classes - which classes to use when</h2>
+<p>The concrete classes are for use in code that actually needs to store string data. The most common uses of the concrete classes are as local variables, and members in classes or structs. Whereas the abstract classes differ in storage mechansim, for the most part the concrete classes differ in storage policy.</p>
+<p>The following is a list of the most common concrete classes. Once you are familiar with them, see the appendix describing <a href="#Appendix_A_-_What_class_to_use_when">What Class to Use When.</a></p>
+<ul>
+ <li><code><b>nsString / nsCString</b></code>- a null-terminated string whose buffer is allocated on the heap. Destroys its buffer when the string object goes away.</li>
+ <li><code><b>nsAutoString / nsCAutoString</b></code>- derived from <code>nsString</code>, a string which owns a 64 code unit buffer in the same storage space as the string itself. If a string less than 64 code units is assigned to an <code>nsAutoString</code>, then no extra storage will be allocated. For larger strings, a new buffer is allocated on the heap.</li>
+ <li><code><b>nsXPIDLString / nsXPIDLCString</b></code>- derived from <code>nsString</code>, this class supports the <code>getter_Copies()</code> operator which allows easy access to XPIDL <code>out wstring / string</code> parameters. This class also supports the notion of a null-valued buffer, whereas <code>nsString</code>'s buffer is never null.</li>
+ <li><code><b>nsDependentString</b></code>- derived from <code>nsString</code>, this string does
+ <i>
+ not</i>
+ own its buffer. It is useful for converting a raw string (<code>const PRUnichar*</code> or <code>const char*</code>) into a class of type <code>nsAString</code>.</li>
+ <li><code><b>nsPrintfCString</b></code>- derived from <code>nsCString</code>, this string behaves like an <code>nsCAutoString</code>. The constructor takes parameters which allows it to construct a 8-bit string from a <code>printf</code>-style format string and parameter list.</li>
+ <li><code><b>NS_LITERAL_STRING/NS_NAMED_LITERAL_STRING</b></code>- these convert a literal string (such as "abc") to a <code>nsString</code> or a subclass of <code>nsString</code>. On platforms supporting double-byte string literals (e.g., MSVC++ or GCC with the -fshort-wchar option), these are simply macros around the <code>nsDependentString</code> class. They are slightly faster than just wrapping them with an <code>nsDependentString</code> because they use the compiler to calculate their length, and they also hide the messy cross-platform details of non-byte literal strings.</li>
+</ul>
+<p>There are also a number of concrete classes that are created as a side-effect of helper routines, etc. You should avoid direct use of these classes. Let the string library create the class for you.</p>
+<ul>
+ <li><code><b>nsSubstringTuple</b></code> - created via <a href="#String_Concatenation">string concatenation</a></li>
+ <li><code><b>nsDependentSubstring</b></code> - created through <a href="#Substrings_.28string_fragments.29">Substring</a></li>
+ <li><code><b>nsPromiseFlatString</b></code> - created through <code><b><a href="#Raw_Character_Pointers">PromiseFlatString()</a></b></code></li>
+</ul>
+<p>Of course, there are times when it is necessary to reference these string classes in your code, but as a general rule they should be avoided.</p>
+<h2 id="Iterators" name="Iterators">Iterators</h2>
+<p>Iterators are objects that retain a reference to a position in a string. In some ways they are like a number which refers to an index in an array, or a character-pointer that refers to a position in a character string. They also provide a syntactic means to distinguish between reading and writing to a string.</p>
+<p>Iterators are most often used to extract substrings of a string. They provide the capability to modify the contents of a string, but often helper routines, or the string's own methods are quicker at complex string transformations.</p>
+<p>Iterators are declared from the string class which they are iterating:</p>
+<pre class="eval">nsAString::const_iterator start, end; // reading-only iterators for nsAString
+nsString::iterator substr_start, substr_end; // writing iterators for nsString
+</pre>
+<p>Iterators are initialized with one of 4 methods on the string you wish to reference:</p>
+<pre class="eval">// let's read from 'str'
+str.BeginReading(start); // initialize 'start' to the beginning of 'str'
+str.EndReading(end); // 'end' will be at the end of the string
+
+// say we also want to write to 'url'
+url.BeginWriting(substr_start);
+url.EndWriting(substr_end);
+</pre>
+<p>You can access the code unit that an iterator points to with the dereference operator *.</p>
+<pre class="eval">if (*start == '[')
+ printf("Starts with a bracket\n");
+</pre>
+<p>Note in the above examples, that '<code>end</code>' and '<code>substr_end</code>' will actually point to the code unit past the end of the string, so you should never dereference the direct result of <code>.EndReading()</code>.</p>
+<p>You can test if two iterators point to the same position with == or !=. You can advance iterators with ++. Putting the ++ before your iterator is preferred, and will prevent creation of a temporary iterator.</p>
+<pre class="eval">while (start != end) // iterate through the whole string
+ ++start;
+</pre>
+<p>You can effectively write to a string with writing iterators (as opposed to const-iterators):</p>
+<pre class="eval">// change all * to !
+while (substr_start != substr_end) {
+ if (*substr_start == '*')
+ *substr_start = '!';
+ ++substr_start;
+}
+</pre>
+<p>With the patch for <a class="external" href="http://bugzilla.mozilla.org/show_bug.cgi?id=231995">bug 231995</a>, this loop is now as efficient as iterating with raw character pointers.</p>
+<h2 id="Helper_Classes_and_Functions" name="Helper_Classes_and_Functions">Helper Classes and Functions</h2>
+<h3 id="Searching_strings_-_looking_for_substrings.2C_characters.2C_etc." name="Searching_strings_-_looking_for_substrings.2C_characters.2C_etc.">Searching strings - looking for substrings, characters, etc.</h3>
+<p><code>FindInReadable()</code> is the replacement for the old <code>string.Find(..)</code>. The syntax is:</p>
+<pre class="eval">PRBool FindInReadable(const nsAString&amp; pattern,
+ nsAString::const_iterator start, nsAString::const_iterator end,
+ nsStringComparator&amp; aComparator = nsDefaultStringComparator());
+</pre>
+<p>To use this, <code>start</code> and <code>end</code> should point to the beginning and end of a string that you would like to search. If the search string is found, <code>start</code> and <code>end</code> will be adjusted to point to the beginning and end of the found pattern. The return value is PR_TRUE or PR_FALSE, indicating whether or not the string was found.</p>
+<p>An example:</p>
+<pre class="eval">const nsAString&amp; str = GetSomeString();
+nsAString::const_iterator start, end;
+
+str.BeginReading(start);
+str.EndReading(end);
+
+NS_NAMED_LITERAL_STRING(valuePrefix, "value=");
+
+if (FindInReadable(valuePrefix, start, end)) {
+ // end now points to the character after the pattern
+ valueStart = end;
+
+}
+</pre>
+<h3 id="Memory_Allocation_-_how_to_avoid_it.2C_which_methods_to_use" name="Memory_Allocation_-_how_to_avoid_it.2C_which_methods_to_use">Memory Allocation - how to avoid it, which methods to use</h3>
+<p>The preferred method to allocate a new character buffer (<code>PRUnichar*</code>/<code>char*</code>) from an existing string is with one of the following methods:</p>
+<ul>
+ <li><code><b>PRUnichar* ToNewUnicode(
+ <i>
+ nsAString&amp;</i>
+ )</b></code> - Allocates a <code>PRUnichar*</code>buffer from an <code>nsAString</code>.</li>
+ <li><code><b>char *ToNewCString(
+ <i>
+ nsACString&amp;</i>
+ )</b></code> - Allocates a <code>char*</code>buffer from an <code>nsACString</code>. Note that this method will also work on nsAStrings, but it will do an implicit <a href="#Lossy_Conversion">lossy conversion</a>. This function should only be used if the input is known to be strictly ASCII. Often a conversion to UTF-8 is more appropriate. See <code><b>ToNewUTF8String</b></code> below.</li>
+ <li><code><b>char* ToNewUTF8String(
+ <i>
+ nsAString&amp;</i>
+ )</b></code> - Allocates a new <code>char*</code> buffer containing the UTF-8 encoded version of the given nsAString. See <a href="#Unicode_Conversion_ns.2ACString_vs._ns.2AString">Unicode Conversion</a> for more details.</li>
+</ul>
+<p>These methods return a buffer allocated using XPCOM's allocator (<code>nsMemory::Alloc</code>) instead of the traditional allocator (<code>malloc</code>, etc.). You should use <code>nsMemory::Free</code> to deallocate the result when you no longer need it.</p>
+<h3 id="Substrings_.28string_fragments.29" name="Substrings_.28string_fragments.29">Substrings (string fragments)</h3>
+<p>It is very simple to refer to a substring of an existing string without actually allocating new space and copying the characters into that substring. <code>Substring()</code> is the preferred method to create a reference to such a string.</p>
+<pre class="eval">void ProcessString(const nsAString&amp; str) {
+ const nsAString&amp; firstFive = Substring(str, 0, 5);
+ // firstFive is now a string representing the first 5 characters
+}
+</pre>
+<h2 id="Unicode_Conversion_ns.2ACString_vs._ns.2AString" name="Unicode_Conversion_ns.2ACString_vs._ns.2AString">Unicode Conversion ns*CString vs. ns*String</h2>
+<p>Strings can be
+ <i>
+ stored</i>
+ in two basic formats: 8-bit code unit (byte/<code>char</code>) strings, or 16-bit code unit (<code>PRUnichar</code>) strings. Any string class with a capital "C" in the classname contains 8-bit bytes. These classes include <code>nsCString</code>, <code>nsDependentCString</code>, and so forth. Any string class
+ <i>
+ without</i>
+ the "C" contains 16-bit code units.</p>
+<p>A 8-bit string can be in one of many character encodings while a 16-bit string is always in UTF-16. The most common encodings are:</p>
+<ul>
+ <li>ASCII - 8-bit encoding for basic English-only strings. Each ASCII value is stored in exactly one byte in the array.</li>
+ <li><a class="external" href="http://www.unicode.org/glossary/#UCS_2">UCS2</a> - 16-bit encoding for a
+ <i>
+ subset</i>
+ of Unicode, <a class="external" href="http://www.unicode.org/glossary/#BMP">BMP</a>. The Unicode value of a character stored in UCS2 is stored in exactly one 16-bit <code>PRUnichar</code> in a string class.</li>
+ <li><a class="external" href="http://www.faqs.org/rfcs/rfc3629.html">UTF-8</a> - 8-bit encoding for Unicode characters. Each Unicode characters is stored in up to 4 bytes in a string class. UTF-8 is capable of representing the entire Unicode character repertoire, and it efficiently maps to <a class="external" href="http://www.unicode.org/glossary/#UTF_32">UTF-32</a>.</li>
+ <li><a class="external" href="http://www.unicode.org/glossary/#UTF_16">UTF-16</a> - 16-bit encoding for Unicode storage, backwards compatible with UCS2. The Unicode value of a character stored in UTF-16 may require
+ <i>
+ one or two</i>
+ 16-bit <code>PRUnichar</code>s in a string class. The contents of <code>nsAString</code> always has to be regarded as in this encoding instead of UCS2. UTF-16 is capable of representing the entire Unicode character repertoire, and it efficiently maps to UTF-32. (Win32 W APIs and Mac OS X natively use UTF-16.)</li>
+</ul>
+<p>In addition, there are literally hundreds of encodings that are provided by internationalization libraries. Access to these libraries may be part of the application (such as <code>nsICharsetConversionManager</code> in Mozilla) or built into the operating system (such as <code>iconv()</code> in UNIX operating systems and <code>MultiByteToWideChar</code>/<code>WideCharToMultiByte</code> on Windows).</p>
+<p>When working with existing code, it is important to examine the current usage of the strings that you are manipulating, to determine the correct conversion mechanism.</p>
+<p>When writing new code, it can be confusing to know which storage class and encoding is the most appropriate. There is no single answer to this question, but there are a few important guidelines:</p>
+<ul>
+ <li><b>Is the string always ASCII?</b> First and foremost, you need to determine what kinds of values will be stored in the string. If the strings are always internal, ASCII strings such as "left", "true", "background" and so forth, then straight C-strings are probably the way to go.</li>
+ <li><b>If the string is ASCII, will it be compared to, assigned to, or otherwise interact with non-ASCII strings?</b> When assigning or comparing an 8-bit ASCII value (in)to a 16-bit UCS2 string, an "inflation" needs to happen at runtime. If your strings are small enough (say, less than 64 bytes) then it may make sense to store your string in a 16-bit unicode class as well, to avoid the extra conversion. The tradeoff is that your ASCII string takes up twice as much space as a 16-bit Unicode string than it would as an 8-bit string.</li>
+ <li><b>Is the string usually ASCII, but needs to support unicode?</b> If your string is most often ASCII but needs to be able to store Unicode characters, then UTF-8 may be the right encoding. ASCII characters will still be stored in 8-bit storage but other Unicode characters will take up 2 to 4 bytes. However if the string ever needs to be compared or assigned to a 16-bit string, a runtime conversion will be necessary.</li>
+ <li><b>Are you storing large strings of non-ASCII data?</b> Up until this point, UTF-8 might seem like the ideal encoding. The drawback is that for most non-European characters (such as Chinese, Indian and Japanese) in BMP, UTF-8 takes 50% more space than UTF-16. For characters in plane 1 and above, both UTF-8 and UTF-16 take 4 bytes.</li>
+ <li><b>Do you need to manipulate the contents of a Unicode string?</b> One problem with encoding Unicode characters in UTF-8 or other 8-bit storage formats is that the actual Unicode character can span multiple bytes in a string. In most encodings, the actual number of bytes varies from character to character. When you need to iterate over each character, you must take the encoding into account. This is vastly simplified when iterating 16-bit strings because each 16-bit code unit (<code>PRUnichar</code>) corresponds to a Unicode character as long as all characters are in BMP, which is often the case. However, you have to keep in mind that a single Unicode character in plane 1 and beyond is represented in two 16-bit code units in 16-bit strings so that the number of <code>PRUnichar</code>'s is
+ <i>
+ not</i>
+ always equal to the number of Unicode characters. For the same reason, the position and the index in terms of 16-bit code units are not always the same as the position and the index in terms of Unicode characters.</li>
+</ul>
+<p><br>
+ To assist with ASCII, UTF-8, and UTF-16 conversions, there are some helper methods and classes. Some of these classes look like functions, because they are most often used as temporary objects on the stack.</p>
+<h3 id="UTF-8_.2F_UTF-16_conversion" name="UTF-8_.2F_UTF-16_conversion">UTF-8 / UTF-16 conversion</h3>
+<p><code><b>NS_ConvertUTF8toUTF16(
+ <i>
+ const nsACString&amp;</i>
+ )</b></code> - a <code>nsAutoString</code> subclass that converts a UTF-8 encoded <code>nsACString</code> or <code>const char*</code> to a 16-bit UTF-16 string. If you need a <code>const PRUnichar*</code> buffer, you can use the <code>.get()</code> method. For example:</p>
+<pre class="eval">/* signature: void HandleUnicodeString(const nsAString&amp; str); */
+object-&gt;HandleUnicodeString(<b>NS_ConvertUTF8toUTF16</b>(utf8String));
+
+/* signature: void HandleUnicodeBuffer(const PRUnichar* str); */
+object-&gt;HandleUnicodeBuffer(<b>NS_ConvertUTF8toUTF16</b>(utf8String).get());
+</pre>
+<p><code><b>NS_ConvertUTF16toUTF8(
+ <i>
+ const nsAString&amp;</i>
+ )</b></code> - a <code>nsCAutoString</code> which converts a 16-bit UTF-16 string (<code>nsAString</code>) to a UTF-8 encoded string. As above, you can use <code>.get()</code> to access a <code>const char*</code> buffer.</p>
+<pre class="eval">/* signature: void HandleUTF8String(const nsACString&amp; str); */
+object-&gt;HandleUTF8String(<b>NS_ConvertUTF16toUTF8</b>(utf16String));
+
+/* signature: void HandleUTF8Buffer(const char* str); */
+object-&gt;HandleUTF8Buffer(<b>NS_ConvertUTF16toUTF8</b>(utf16String).get());
+</pre>
+<p><code><b>CopyUTF8toUTF16(
+ <i>
+ const nsACString&amp;, nsAString&amp;</i>
+ )</b></code> - converts and copies:</p>
+<pre class="eval">// return a UTF-16 value
+void Foo::GetUnicodeValue(nsAString&amp; result) {
+ <b>CopyUTF8toUTF16</b>(mLocalUTF8Value, result);
+ }
+</pre>
+<p><code><b>AppendUTF8toUTF16(
+ <i>
+ const nsACString&amp;, nsAString&amp;</i>
+ )</b></code> - converts and appends:</p>
+<pre class="eval">// return a UTF-16 value
+void Foo::GetUnicodeValue(nsAString&amp; result) {
+ result.AssignLiteral("prefix:");
+ <b>AppendUTF8toUTF16</b>(mLocalUTF8Value, result);
+}
+</pre>
+<p><br>
+ <code><b>UTF8ToNewUnicode(
+ <i>
+ const nsACString&amp;, PRUint32* aUTF16Count = nsnull</i>
+ )</b></code> - allocates and converts (the optional parameter will contain the number of 16-byte units upon return, if non-null):</p>
+<pre class="eval">void Foo::GetUTF16Value(PRUnichar** result) {
+ *result = <b>UTF8ToNewUnicode</b>(mLocalUTF8Value);
+}
+</pre>
+<p><br>
+ <code><b>CopyUTF16toUTF8(
+ <i>
+ const nsAString&amp;, nsACString&amp;</i>
+ )</b></code> - converts and copies:</p>
+<pre class="eval">// return a UTF-8 value
+void Foo::GetUTF8Value(nsACString&amp; result) {
+ <b>CopyUTF16toUTF8</b>(mLocalUTF16Value, result);
+}
+</pre>
+<p><code><b>AppendUTF16toUTF8(
+ <i>
+ const nsAString&amp;, nsACString&amp;</i>
+ )</b></code> - converts and appends:</p>
+<pre class="eval">// return a UTF-8 value
+void Foo::GetUnicodeValue(nsACString&amp; result) {
+ result.AssignLiteral("prefix:");
+ <b>AppendUTF16toUTF8</b>(mLocalUTF16Value, result);
+}
+</pre>
+<p><code><b>ToNewUTF8String(
+ <i>
+ const nsAString&amp;</i>
+ )</b></code> - allocates and converts:</p>
+<pre class="eval">void Foo::GetUTF8Value(char** result) {
+ *result = <b>ToNewUTF8String</b>(mLocalUTF16Value);
+}
+</pre>
+<h3 id="Lossy_Conversion" name="Lossy_Conversion">Lossy Conversion</h3>
+<p>The following should only be used when you can guarantee that the original string is ASCII. These helpers are very similar to the UTF-8 / UTF-16 conversion helpers above.</p>
+<h4 id="UTF-16_to_ASCII_converters" name="UTF-16_to_ASCII_converters">UTF-16 to ASCII converters</h4>
+<p>These converters are
+ <i>
+ <b>very dangerous</b></i>
+ because they
+ <i>
+ <b>lose information</b></i>
+ during the conversion process. You should
+ <i>
+ <b>avoid UTF-16 to ASCII conversions</b></i>
+ unless your strings are guaranteed to be ASCII. Each 16-bit code unit in 16-bit string is simply cast to an 8-bit byte, which means all Unicode character values above 0xFF are converted to an arbitrary 8-bit byte.</p>
+<ul>
+ <li><code><b>NS_LossyConvertUTF16toASCII(
+ <i>
+ nsAString</i>
+ )</b></code> - a <code>nsCAutoString</code> which holds a temporary buffer containing the deflated value of the string.</li>
+ <li><code><b>LossyCopyUTF16toASCII(
+ <i>
+ nsAString, nsACString</i>
+ )</b></code> - does an in-place conversion from UTF-16 into an ASCII string object.</li>
+ <li><code><b>LossyAppendUTF16toASCII(
+ <i>
+ nsAString, nsACString</i>
+ )</b></code> - appends an UTF-16 string to an ASCII string, losing non-ASCII values.</li>
+ <li><code><b>ToNewCString(
+ <i>
+ nsAString</i>
+ )</b></code> - allocates a new <code>char*</code> string.</li>
+</ul>
+<h4 id="ASCII_to_UTF-16_converters" name="ASCII_to_UTF-16_converters">ASCII to UTF-16 converters</h4>
+<p>These converters are
+ <i>
+ <b>very dangerous</b></i>
+ because they will
+ <i>
+ <b>mangle any non-ASCII string</b></i>
+ into a meaningless UTF-16 string. You should
+ <i>
+ <b>avoid ASCII to UTF-16 conversions</b></i>
+ unless your strings are guaranteed to be ASCII. For instance, if you have an 8-bit string encoded in a multibyte character encoding, each byte of the string will be "inflated" to a 16-bit number by simple casting.</p>
+<p>For example, imagine a UTF-8 string where the first Unicode character of the string is represented with a 3-byte UTF-8 sequence, the "inflated" UTF-16 string will contain the 3 <code>PRUnichar</code>'s instead of the single <code>PRUnichar</code> that represents the first character. These <code>PRUnichar</code>'s have nothing to do with the first Unicode character in the UTF-8 string.</p>
+<ul>
+ <li><code><b>NS_ConvertASCIItoUTF16(
+ <i>
+ nsACString</i>
+ )</b></code> - a <code>nsAutoString</code> which holds a temporary buffer containing the inflated value of the string.</li>
+ <li><code><b>CopyASCIItoUTF16(
+ <i>
+ nsACString, nsAString</i>
+ )</b></code> - does an in-place conversion from one string into a Unicode string object.</li>
+ <li><code><b>AppendASCIItoUTF16(
+ <i>
+ nsACString, nsAString</i>
+ )</b></code> - appends an ASCII string to a Unicode string.</li>
+ <li><code><b>ToNewUnicode(
+ <i>
+ nsACString</i>
+ )</b></code> - Creates a new <code>PRUnichar*</code> string which contains the inflated value.</li>
+</ul>
+<h2 id="Common_Patterns" name="Common_Patterns">Common Patterns</h2>
+<h3 id="Callee-allocated_Parameters" name="Callee-allocated_Parameters">Callee-allocated Parameters</h3>
+<p>Many APIs result in a method allocating a buffer in order to return strings to its caller. This can be tricky because the caller has to remember to free the string when they have finished using it. Fortunately, the <code>nsXPIDLString</code> class makes this very easy.</p>
+<p>A method may look like this:</p>
+<pre class="eval">void GetValue(PRUnichar** aValue)
+{
+ *aValue = ToNewUnicode(foo);
+}
+</pre>
+<p>Without the string classes, the caller would need to free the string:</p>
+<pre>{
+ PRUnichar* val;
+ GetValue(&amp;val);
+
+ if (someCondition) {
+ // don't forget to free the value!
+ nsMemory::Free(val);
+ return NS_ERROR_FAILURE;
+ }
+
+ ...
+ // and later, still don't forget to free!
+ nsMemory::Free(val);
+}
+</pre>
+<p>With <code>nsXPIDLString</code> you never have to worry about this. You can just use <code>getter_Copies()</code> to wrap the string class, and the class will remember to free the buffer when it goes out of scope:</p>
+<pre>{
+ nsXPIDLString val;
+ GetValue(getter_Copies(val));
+
+ // val will free itself here
+ if (someCondition)
+ return NS_ERROR_FAILURE;
+ ...
+ // and later, still nothing to free
+}
+</pre>
+<p>The resulting code is much simpler, and easy to read.</p>
+<h3 id="Literal_Strings" name="Literal_Strings">Literal Strings</h3>
+<p>A
+ <i>
+ literal string</i>
+ is a raw string value that is written in some C++ code. For example, in the statement <code>printf("Hello World\n");</code> the value <code>"Hello World\n"</code> is a literal string. It is often necessary to insert literal string values when an <code>nsAString</code> or <code>nsACString</code> is required. These four macros will provide you with the necessary conversion:</p>
+<ul>
+ <li><code><b>NS_LITERAL_CSTRING(
+ <i>
+ literal string</i>
+ )</b></code> - a temporary <code>nsCString</code></li>
+ <li><code><b>NS_NAMED_LITERAL_CSTRING(
+ <i>
+ variable,literal string</i>
+ )</b></code> - declares a <code>nsCString</code> variable named
+ <i>
+ variable</i>
+ </li>
+ <li><code><b>NS_LITERAL_STRING(
+ <i>
+ literal string</i>
+ )</b></code> - a temporary <code>nsString</code> with the unicode version of
+ <i>
+ literal string</i>
+ </li>
+ <li><code><b>NS_NAMED_LITERAL_STRING(
+ <i>
+ variable,literal string</i>
+ )</b></code> - declares a <code>nsString</code> variable named
+ <i>
+ variable</i>
+ with the unicode version of
+ <i>
+ literal string</i>
+ </li>
+</ul>
+<p>The purpose of the <code>CSTRING</code> versions of these macros may seem unnecessary, given that <code>nsDependentCString</code> will also wrap a string value in an <code>nsCString</code>. The advantage to these macros is that the length of these strings is calculated at compile time, so the string does not need to be scanned at runtime to determine its length.</p>
+<p>The <code>STRING</code> versions of these macros provide a portable way of declaring UTF-16 versions of the given literal string, avoiding runtime conversion on platforms which support literal UTF-16 strings (e.g., MSVC++ and GCC with the -fshort-wchar option).</p>
+<pre>// call Init(const PRUnichar*)
+Init(L"start value"); // bad - L"..." is not portable!
+Init(NS_ConvertASCIItoUTF16("start value").get()); // bad - runtime ASCII-&gt;UTF-16 conversion!
+
+// call Init(const nsAString&amp;)
+Init(nsDependentString(L"start value")); // bad - not portable!
+Init(NS_ConvertASCIItoUTF16("start value")); // bad - runtime ASCII-&gt;UTF-16 conversion!
+
+// call Init(const nsACString&amp;)
+Init(nsDependentCString("start value")); // bad - length determined at runtime
+</pre>
+<p>Here are some examples of proper <code>NS_LITERAL_[C]STRING</code> usage.</p>
+<pre>// call Init(const PRUnichar*)
+Init(NS_LITERAL_STRING("start value").get());
+
+// call Init(const nsAString&amp;)
+Init(NS_LITERAL_STRING("start value"));
+
+// call Init(const nsACString&amp;)
+Init(NS_LITERAL_CSTRING("start value"));
+</pre>
+<p>There are a few details which can be useful in tracking down issues with these macros:</p>
+<p><code>NS_LITERAL_STRING</code> does compile-time conversion to UTF-16 on some platforms (e.g. Windows, Linux, and Mac) but does runtime conversion on other platforms. By using <code>NS_LITERAL_STRING</code> your code is guaranteed to use the best possible conversion for the platform in question.</p>
+<p>Because some platforms do runtime conversion, the use of literal string concatenation inside a <code>NS_LITERAL_STRING/NS_NAMED_LITERAL_STRING</code> macro will compile on these platforms, but not on platforms which support compile-time conversion.</p>
+<p>For example:</p>
+<pre>// call Init(nsAString&amp;)
+Init(NS_LITERAL_STRING("start "
+ "value")); // only compiles on some platforms
+</pre>
+<p>The reason for this is that on some platforms, the <code>L"..."</code> syntax is used, but it is only applied to the first string in the concatenation (<code>"start "</code>). When the compiler attempts to concatenate this with the non-Unicode string <code>"value"</code> it gets confused.</p>
+<p>Also, using preprocessor macros as the string literal is unsupported:</p>
+<pre>#define some_string "See Mozilla Run"
+...
+Init(NS_LITERAL_STRING( some_string )); // only compiles on some platforms/with some compilers.
+
+</pre>
+<h3 id="String_Concatenation" name="String_Concatenation">String Concatenation</h3>
+<p>Strings can be concatenated together using the + operator. The resulting string is a <code>const nsSubstringTuple</code> object. The resulting object can be treated and referenced similarly to a <code>nsAString</code> object. Concatenation
+ <i>
+ does not copy the substrings</i>
+ . The strings are only copied when the concatenation is assigned into another string object. The <code>nsSubstringTuple</code> object holds pointers to the original strings. Therefore, the <code>nsSubstringTuple</code> object is dependent on all of its substrings, meaning that their lifetime must be at least as long as the <code>nsSubstringTuple</code> object.</p>
+<p>For example, you can use the value of two strings and pass their concatenation on to another function which takes an <code>const nsAString&amp;:</code></p>
+<pre class="eval">void HandleTwoStrings(const nsAString&amp; one, const nsAString&amp; two) {
+ // call HandleString(const nsAString&amp;)
+ HandleString(one + two);
+}
+</pre>
+<p>NOTE: The two strings are implicitly combined into a temporary <code>nsString</code> in this case, and the temporary string is passed into <code>HandleString</code>. If <code>HandleString</code> assigns its input into another <code>nsString</code>, then the string buffer will be shared in this case negating the cost of the intermediate temporary. You can concatenate N strings and store the result in a temporary variable:</p>
+<pre class="eval">NS_NAMED_LITERAL_STRING(start, "start ");
+NS_NAMED_LITERAL_STRING(middle, "middle ");
+NS_NAMED_LITERAL_STRING(end, "end");
+// create a string with 3 dependent fragments - no copying involved!
+nsString combinedString = start + middle + end;
+
+// call void HandleString(const nsAString&amp;);
+HandleString(combinedString);
+</pre>
+<p>If you are using <code>NS_LITERAL_STRING</code> to create a temporary that is only used once, then it is safe to define it inside a concatenation because the string buffer will live as long as the temporary concatenation object (of type <code>nsSubstringTuple</code>).</p>
+<pre class="eval">// call HandlePage(const nsAString&amp;);
+// safe because the concatenated-string will live as long as its substrings
+HandlePage(NS_LITERAL_STRING("start ") + NS_LITERAL_STRING("end"));
+</pre>
+<h3 id="Local_variables" name="Local_variables">Local variables</h3>
+<p>Local variables within a function are usually stored on the stack. The <code>nsAutoString/nsCAutoString</code> classes are derivatives of the <code>nsString/nsCString classes</code>. They own a 64-character buffer allocated in the same storage space as the string itself. If the <code>nsAutoString</code> is allocated on the stack, then it has at its disposal a 64-character stack buffer. This allows the implementation to avoid allocating extra memory when dealing with small strings.</p>
+<pre class="eval">...
+nsAutoString value;
+GetValue(value); // if the result is less than 64 code units,
+ // then this just saved us an allocation
+...
+</pre>
+<h3 id="Member_variables" name="Member_variables">Member variables</h3>
+<p>In general, you should use the concrete classes <code>nsString</code> and <code>nsCString</code> for member variables.</p>
+<pre class="eval">class Foo {
+ ...
+ // these store UTF-8 and UTF-16 values respectively
+ nsCString mLocalName;
+ nsString mTitle;
+};
+</pre>
+<p>Note that the strings are declared directly in the class, not as pointers to strings. Don't do this:</p>
+<pre>class Foo {
+public:
+ Foo() {
+ mLocalName = new nsCString();
+ mTitle = new nsString();
+ }
+ ~Foo() { delete mLocalName; delete mTitle; }
+
+private:
+ // these store UTF-8 and UTF-16 values respectively
+ nsCString* mLocalName;
+ nsString* mTitle;
+};
+</pre>
+<p>The above code may appear to save the cost of the string objects, but <code>nsString/nsCString</code> are small objects - the overhead of the allocation outweighs the few bytes you'd save by keeping a pointer.</p>
+<p>Another common incorrect pattern is to use <code>nsAutoString/nsCAutoString</code> for member variables. As described in <a href="#Local_variables">Local Variables</a>, these classes have a built in buffer that make them very large. This means that if you include them in a class, they bloat the class by 64 bytes (<code>nsCAutoString</code>) or 128 bytes (<code>nsAutoString</code>).</p>
+<p>An example:</p>
+<pre>class Foo {
+ ...
+
+ // bloats 'Foo' by 128 bytes!
+ nsAutoString mLocalName;
+};
+</pre>
+<h3 id="Raw_Character_Pointers" name="Raw_Character_Pointers">Raw Character Pointers</h3>
+<p><code>PromiseFlatString()</code> can be used to create a temporary buffer which holds a null-terminated buffer containing the same value as the source string. <code>PromiseFlatString()</code> will create a temporary buffer if necessary. This is most often used in order to pass an <code>nsAString</code> to an API which requires a null-terminated string.</p>
+<p>In the following example, an <code>nsAString</code> is combined with a literal string, and the result is passed to an API which requires a simple character buffer.</p>
+<pre class="eval">// Modify the URL and pass to AddPage(const PRUnichar* url)
+void AddModifiedPage(const nsAString&amp; url) {
+ NS_NAMED_LITERAL_STRING(httpPrefix, <span class="nowiki">"http://"</span>);
+ const nsAString&amp; modifiedURL = httpPrefix + url;
+
+ // creates a temporary buffer
+ AddPage(PromiseFlatString(modifiedURL).get());
+}
+</pre>
+<p><code>PromiseFlatString()</code> is smart when handed a string that is already null-terminated. It avoids creating the temporary buffer in such cases.</p>
+<pre class="eval">// Modify the URL and pass to AddPage(const PRUnichar* url)
+void AddModifiedPage(const nsAString&amp; url, PRBool addPrefix) {
+ if (addPrefix) {
+ // MUST create a temporary buffer - string is multi-fragmented
+ NS_NAMED_LITERAL_STRING(httpPrefix, <span class="nowiki">"http://"</span>);
+ AddPage(PromiseFlatString(httpPrefix + modifiedURL));
+ } else {
+ // MIGHT create a temporary buffer, does a runtime check
+ AddPage(PromiseFlatString(url).get());
+ }
+}
+</pre>
+<h3 id="printf_and_a_UTF-16_string" name="printf_and_a_UTF-16_string"><code>printf</code> and a UTF-16 string</h3>
+<p>For debugging, it's useful to <code>printf</code> a UTF-16 string (nsString, nsAutoString, nsXPIDLString, etc). To do this usually requires converting it to an 8-bit string, because that's what printf expects. However, on Windows, the following should work:</p>
+<pre class="eval">printf("%S\n", yourString.get());
+</pre>
+<p>(Note: I didn't test this. Also, I'm not sure what exactly this does to non-ASCII characters, especially when they are outside the system codepage). The reason that this doesn't work on Unix is because a wchar_t, which is what %S expects, is usually 4 bytes there (even when Mozilla is compiled with -fshort-wchar, because this would require libc to be compiled with -fshort-wchar).</p>
+<p>If non-ASCII characters aren't important, use:</p>
+<pre class="eval">printf("%s\n", NS_LossyConvertUTF16toASCII(yourString).get());
+</pre>
+<p>On platforms that use UTF-8 for console output (most Linux distributions), this works:</p>
+<pre class="eval">printf("%s\n", NS_ConvertUTF16toUTF8(yourString).get());
+</pre>
+<h2 id="IDL" name="IDL">IDL</h2>
+<p>The string library is also available through IDL. By declaring attributes and methods using the specially defined IDL types, string classes are used as parameters to the corresponding methods.</p>
+<h3 id="IDL_String_types" name="IDL_String_types">IDL String types</h3>
+<p>The C++ signatures follow the abstract-type convention described above, such that all method parameters are based on the <a href="#The_Abstract_Classes">abstract classes</a>. The following table describes the purpose of each string type in IDL.</p>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th class="header">IDL type</th>
+ <th class="header">C++ Type</th>
+ <th class="header">Purpose</th>
+ </tr>
+ <tr>
+ <td><code>string</code></td>
+ <td><code>char*</code></td>
+ <td>Raw character pointer to ASCII (7-bit) string, no string classes used. High bit is not guaranteed across XPConnect boundaries</td>
+ </tr>
+ <tr>
+ <td><code>wstring</code></td>
+ <td><code>PRUnichar*</code></td>
+ <td>Raw character pointer to UTF-16 string, no string classes used</td>
+ </tr>
+ <tr>
+ <td><code>AString</code></td>
+ <td><code>nsAString</code></td>
+ <td>UTF-16 string</td>
+ </tr>
+ <tr>
+ <td><code>ACString</code></td>
+ <td><code>nsACString</code></td>
+ <td>8-bit string, all bits are preserved across XPConnect boundaries</td>
+ </tr>
+ <tr>
+ <td><code>AUTF8String</code></td>
+ <td><code>nsACString</code></td>
+ <td>UTF-8 string - converted to UTF-16 as necessary when value is used across XPConnect boundaries</td>
+ </tr>
+ <tr>
+ <td><code>DOMString</code></td>
+ <td><code>nsAString</code></td>
+ <td>UTF-16 string used in the DOM. More or less the same as <code>AString</code>, but in JavaScript it has no distinction between whether the string is void or just empty. (not sure on this, looking for corrections.</td>
+ </tr>
+ </tbody>
+</table>
+<h3 id="C.2B.2B_Signatures" name="C.2B.2B_Signatures">C++ Signatures</h3>
+<p>In IDL, <code>in</code> parameters are read-only, and the C++ signatures for <code>*String</code> parameters follows the above guidelines by using <code>const nsAString&amp;</code> for these parameters. <code>out</code> and <code>inout</code> parameters are defined simply as <code>nsAString</code> so that the callee can write to them.</p>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th class="header">IDL</th>
+ <th class="header">C++</th>
+ </tr>
+ <tr>
+ <td>
+ <pre class="eval">
+interface nsIFoo : nsISupports {
+
+ attribute AString utf16String;
+
+
+
+
+ AUTF8String getValue(in ACString key);
+
+};
+</pre>
+ </td>
+ <td>
+ <pre class="eval">
+class nsIFoo : public nsISupports {
+
+ NS_IMETHOD GetUtf16String(nsAString&amp;
+ aResult) = 0;
+ NS_IMETHOD SetUtf16String(const nsAString&amp;
+ aValue) = 0;
+
+ NS_IMETHOD GetValue(const nsACString&amp; aKey,
+ nsACString&amp; aResult) = 0;
+};
+</pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<p>In the above example, <code>utf16String</code> is treated as a UTF-16 string. The implementation of <code>GetUtf16String()</code> will use <code>aResult.Assign</code> to "return" the value. In <code>SetUtf16String()</code> the value of the string can be used through a variety of methods including <a href="#Iterators">Iterators</a>, <code><a href="#Raw_Character_Pointers">PromiseFlatString</a></code>, and assignment to other strings.</p>
+<p>In <code>GetValue()</code>, the first parameter, <code>aKey</code>, is treated as a raw sequence of 8-bit values. Any non-ASCII characters in <code>aKey</code> will be preserved when crossing XPConnect boundaries. The implementation of <code>GetValue()</code> will assign a UTF-8 encoded 8-bit string into <code>aResult</code>. If the <code>this</code> method is called across XPConnect boundaries, such as from a script, then the result will be decoded from UTF-8 into UTF-16 and used as a Unicode value.</p>
+<h3 id="Choosing_a_string_type" name="Choosing_a_string_type">Choosing a string type</h3>
+<p>It can be difficult to determine the correct string type to use for IDL. The following points should help determine the appropriate string type.</p>
+<ul>
+ <li>Using string classes may avoid new memory allocation for <code>out</code> parameters. For example, if the caller is using an <code>nsAutoString</code> to receive the value for an <code>out</code> parameter, (defined in C++ as simply <code>nsAString&amp;</code> then assignment of short (less than 64-characters) values to an <code>out</code> parameter will only copy the value into the <code>nsAutoString</code>'s buffer. Moreover, using the string classes allows for sharing of string buffers. In many cases, assigning from one string object to another avoids copying in favor of simply incrementing a reference count.</li>
+ <li><code>in</code> strings using string classes often have their length pre-calculated. This can be a performance win.</li>
+ <li>In cases where a raw-character buffer is required, <code>string</code> and <code>wstring</code> provide faster access than <code>PromiseFlatString</code>.</li>
+ <li>UTF-8 strings defined with <code>AUTF8String</code> may need to be decoded when crossing XPConnect boundaries. This can be a performance hit. On the other hand, UTF-8 strings take up less space for strings that are commonly ASCII.</li>
+ <li>UTF-16 strings defined with <code>wstring</code> or <code>AString</code> are fast when the unicode value is required. However, if the value is more often ASCII, then half of the storage space of the underlying string may be wasted.</li>
+</ul>
+<h2 id="Appendix_A_-_What_class_to_use_when" name="Appendix_A_-_What_class_to_use_when">Appendix A - What class to use when</h2>
+<p>This table provides a quick reference for what classes you should be using.</p>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th class="header">Context</th>
+ <th class="header">class</th>
+ <th class="header">Notes</th>
+ </tr>
+ <tr>
+ <td>Local Variables</td>
+ <td><code>nsAutoString<br>
+ nsCAutoString</code></td>
+ <td> </td>
+ </tr>
+ <tr>
+ <td>Class Member Variables</td>
+ <td><code>nsString<br>
+ nsCString</code></td>
+ <td> </td>
+ </tr>
+ <tr>
+ <td>Method Parameter types</td>
+ <td><code>nsAString<br>
+ nsACString</code></td>
+ <td>Use abstract classes for parameters. Use <code>const nsAString&amp;</code> for "in" parameters and <code>nsAString&amp;</code> for "out" parameters.</td>
+ </tr>
+ <tr>
+ <td>Retrieving "out" string/wstrings</td>
+ <td><code>nsXPIDLString<br>
+ nsXPIDLCString</code></td>
+ <td>Use <code>getter_Copies()</code>. Similar to <code>nsString / nsCString</code>.</td>
+ </tr>
+ <tr>
+ <td>Wrapping character buffers</td>
+ <td><code>nsDependentString<br>
+ nsDependentCString</code></td>
+ <td>Wrap <code>const char* / const PRUnichar*</code> buffers.</td>
+ </tr>
+ <tr>
+ <td>Literal strings</td>
+ <td><code>NS_LITERAL_STRING<br>
+ NS_LITERAL_CSTRING</code></td>
+ <td>Similar to <code>nsDependent[C]String</code>, but pre-calculates length at build time.</td>
+ </tr>
+ </tbody>
+</table>
+<h2 id="Appendix_B_-_nsAString_Reference" name="Appendix_B_-_nsAString_Reference">Appendix B - nsAString Reference</h2>
+<p>Read-only methods.</p>
+<ul>
+ <li><code><b>Length()</b></code></li>
+ <li><code><b>IsEmpty()</b></code></li>
+ <li><code><b>IsVoid()</b></code> - XPConnect will convert void nsAStrings to JavaScript <code>null</code>.</li>
+ <li><code><b>BeginReading(
+ <i>
+ iterator</i>
+ )</b></code></li>
+ <li><code><b>EndReading(
+ <i>
+ iterator</i>
+ )</b></code></li>
+ <li><code><b>Equals(
+ <i>
+ string[, comparator]</i>
+ )</b></code></li>
+ <li><code><b>First()</b></code></li>
+ <li><code><b>Last()</b></code></li>
+ <li><code><b>CountChar()</b></code></li>
+ <li><code><b>Left(
+ <i>
+ outstring, length</i>
+ )</b></code></li>
+ <li><code><b>Mid(
+ <i>
+ outstring, position, length</i>
+ )</b></code></li>
+ <li><code><b>Right(
+ <i>
+ outstring, length</i>
+ )</b></code></li>
+ <li><code><b>FindChar(
+ <i>
+ character</i>
+ )</b></code></li>
+</ul>
+<p>Methods that modify the string.</p>
+<ul>
+ <li><code><b>Assign(
+ <i>
+ string</i>
+ )</b></code></li>
+ <li><code><b>Append(
+ <i>
+ string</i>
+ )</b></code></li>
+ <li><code><b>Insert(
+ <i>
+ string</i>
+ )</b></code></li>
+ <li><code><b>Cut(
+ <i>
+ start, length</i>
+ )</b></code></li>
+ <li><code><b>Replace(
+ <i>
+ start, length, string</i>
+ )</b></code></li>
+ <li><code><b>Truncate(
+ <i>
+ length</i>
+ )</b></code></li>
+ <li><code><b>SetIsVoid(
+ <i>
+ state</i>
+ )</b></code> - XPConnect will convert void nsAStrings to JavaScript <code>null</code>.</li>
+ <li><code><b>BeginWriting(
+ <i>
+ iterator</i>
+ )</b></code></li>
+ <li><code><b>EndWriting(
+ <i>
+ iterator</i>
+ )</b></code></li>
+ <li><code><b>SetCapacity()</b></code></li>
+</ul>
diff --git a/files/zh-cn/mozilla/tech/xpcom/index.html b/files/zh-cn/mozilla/tech/xpcom/index.html
new file mode 100644
index 0000000000..98620642db
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/index.html
@@ -0,0 +1,44 @@
+---
+title: XPCOM
+slug: Mozilla/Tech/XPCOM
+tags:
+ - XPCOM
+ - 所有分类
+translation_of: Mozilla/Tech/XPCOM
+---
+<p><strong>XPCOM</strong>(Cross Platform Component Object Model)是一种跨平台组件对象模型,其原理与微软的COM技术类似,它支持多种语言绑定(<a href="cn/XPCOM/Language_Bindings">Language Bindings</a>)。也就是说,我们可以使用C++、JAVA、JavaScript、Python、Ruby、Perl等语言来编写组件。而XPCOM的接口是用一种叫做<a href="cn/XPIDL">XPIDL</a>的IDL(Interface Description Language)来定义的。</p>
+
+<div>
+<p>XPCOM 本身提供了一套核心的组件和类,用于诸如内存管理,线程,基本数据结构(strings, arrays, variants)等 。但是大部分的XPCOM组件并不是这个核心库提供的,而是由很多第三方的平台(例如<a href="cn/Gecko">Gecko</a>或者<a href="Necko">Necko</a>)提供,或者由一个应用,甚至一个扩展提供。</p>
+
+<p> </p>
+
+<p></p><div class="row topicpage-table">
+ <div class="section"><dl><dl><dt class="landingPageList"><a href="/zh-CN/docs/Generic_factory">Generic factory</a></dt><dd class="landingPageList">Most XPCOM factories can be very simple. Rick Potts wrote a templated-based generic factory (nsFactory&lt;t&gt;) that simplifies the factory creation process that just requires writing a CreateInstance() method. The new nsIGenericFactory interface takes this a step further, by providing a single interface that can be reused anytime a simple implementation of nsIFactory is needed. Here is the interface, and a description of its use.&lt;/t&gt;</dd><dt class="landingPageList"><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Observer_Notifications">Observer Notifications</a></dt><dd class="landingPageList">The following are topics that you can observe during the course of an application. Unless otherwise noted you register for the topics using the <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIObserverService" title="">nsIObserverService</a></code>.</dd><dt class="landingPageList"><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Setting_HTTP_request_headers">Setting HTTP request headers</a></dt><dd class="landingPageList"><a href="https://developer.mozilla.org/en-US/docs/HTTP">HTTP</a> 是网络背后的核心技术之一。除了实质内容之外,一些重要的信息通过HTTP 头传递给HTTP 请求和响应。</dd><dt class="landingPageList"><a href="/zh-CN/docs/Storage">Storage</a></dt><dd class="landingPageList"><strong>Storage</strong> 存储是一个 <a class="external" href="http://www.sqlite.org/">SQLite</a> 数据库API。它可用于受信任的调用者,仅限于扩展和Firefox组件。</dd><dt class="landingPageList"><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Glue">XPCOM Glue</a></dt><dd class="landingPageList">The XPCOM Glue is a static library which component developers and embedders can link against. It allows developers to link only against the frozen XPCOM method symbols and maintain compatibility with multiple versions of XPCOM.</dd><dt class="landingPageList"><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference">XPCOM reference</a></dt><dd class="landingPageList">This reference describes the interfaces and functions provided by the <a href="/en-US/docs/Mozilla/Tech/XPCOM">XPCOM</a> library. In addition, it details the various helper classes and functions, as well as the components, provided by the <a href="/en-US/docs/Mozilla/Tech/XPCOM/Glue">XPCOM glue</a> library. The contents herein are oriented primarily toward extension developers and people embedding XPCOM in other projects.</dd></dl></dl></div>
+ <div class="section"><dl><dt class="landingPageList"><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Guide">XPCOM 指南</a></dt><dd class="landingPageList">本文提供了关于 XPCOM 的说明和使用文档,包括如何在你的工程中使用,如何为你的 Firefox 扩展等构建 XPCOM 组件。</dd><dt class="landingPageList"><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Interfacing_with_the_XPCOM_cycle_collector">与XPCOM cycle collector交互</a></dt><dd class="landingPageList">本文是对于在Firefox 3的XPCOM中引入的cycle collector的一个简要描述,描述了将一个已有的C++类修改为一个XPCOM cycle collection中的参与项的步骤。如果你认为你有关于类的循环引用导致的内存泄漏,那可以看看这个。</dd><dt class="landingPageList"><a href="/zh-CN/docs/Using_the_Clipboard">使用剪贴板</a></dt><dd class="landingPageList">This section provides information about cutting, copying and pasting to and from the clipboard.</dd><dt class="landingPageList"><a href="/zh-CN/docs/Creating_a_Python_XPCOM_component">创建Python XPCOM组件</a></dt><dd class="landingPageList"><a href="http://books.mozdev.org/html"><em>Creating Applications with Mozilla</em></a> 已经包含了一个<a href="http://books.mozdev.org/html/mozilla-chp-8-sect-2.html" title="http://books.mozdev.org/html/mozilla-chp-8-sect-2.html">教程</a>用于编写简单的基于JavaScript和C++(实现<code>nsISimple</code>接口)的组件,本文阐述如何通过Python语言使用<a href="/en-US/docs/PyXPCOM" title="/en-US/docs/PyXPCOM">PyXPCOM</a>创建相同的组件。</dd><dt class="landingPageList"><a href="/zh-CN/docs/Aggregating_the_In-Memory_Datasource">收集 In-Memory 数据源</a></dt><dd class="landingPageList"></dd><dt class="landingPageList"><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Language_Bindings">语言绑定</a></dt><dd class="landingPageList">一款 <strong>XPCOM 的语言绑定</strong>是连接某种特定的程序设计语言与 <a href="/cn/XPCOM" title="cn/XPCOM">XPCOM</a> 之间的纽带,它用来提供从语言到 XPCOM 对象的访问, 并且将此种语言写成的模块作为其他进行 XPCOM 绑定的程序语言的 XPCOM 对象。</dd></dl></div>
+ </div><p></p>
+
+<p></p><div class="blockIndicator communitybox">
+
+ <div class="column-container">
+ <h2 id="加入_XPCOM_社区">加入 XPCOM 社区</h2>
+ <div class="column-half">
+ <div class="communitysubhead">请选择你喜欢的方式加入我们:</div>
+ <ul class="communitymailinglist">
+ <li><a href="https://lists.mozilla.org/listinfo/dev-tech-xpcom"> 邮件列表</a></li>
+
+
+ <li><a href="http://groups.google.com/group/mozilla.dev.tech.xpcom"> 新闻组</a></li>
+ <li><a href="http://groups.google.com/group/mozilla.dev.tech.xpcom/feeds"> Web feed</a></li>
+</ul>
+ </div>
+ <div class="column-half">
+ <ul class="communitycontact"><li><strong>IRC: </strong><a href="irc://irc.mozilla.org/developers">#developers</a> <span class="smaller">(<a href="https://wiki.mozilla.org/IRC">了解 IRC</a>)</span></li><li><strong>Tools: </strong><a href="http://ted.mielczarek.org/code/mozilla/jscomponentwiz/">JavaScript Component Wizard</a>, <a href="http://www.mytools360.com-a.googlepages.com/home#XPComPro">Visual C++ Component Wizard</a>, <a href="http://www.yutools.com/wp/tools/yuxpcomwizard/?lang=en">Visual C++ Component Wizard for Visual Studio 2010</a></li></ul>
+ </div>
+ </div>
+</div><p></p>
+
+<p></p><section id="Quick_Links"><ol><li><a href="http://www.ibm.com/developerworks/library/os-xpcomfirefox/">Tutorial from IBM DeveloperWorks</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Creating_Custom_Firefox_Extensions_with_the_Mozilla_Build_System">Binary components tutorial</a></li><li><a href="http://www.iosart.com/firefox/xpcom/">Linux and Windows how-to guide</a></li><li><a href="http://starkravingfinkle.org/blog/2006/10/mozilla-platform-xpcom-in-c/">Windows example blog post</a></li><li><a href="http://wanderingstan.com/2007-11-16/geekout_how_to_make_a_c_xpcom_component">Another Windows example</a></li><li><a href="http://rcrowley.org/2007/07/17/cross-platform-xpcom-a-howto.html">Mac OS X example</a></li><li><a href="/en-US/docs/Web/JavaScript" title="JavaScript (JS) is a lightweight interpreted or JIT-compiled programming language with first-class functions. While it is most well-known as the scripting language for Web pages, many non-browser environments also use it, such as Node.js, Apache CouchDB and Adobe Acrobat.">JavaScript</a></li></ol></section><p></p>
+</div>
+
+<p> </p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/interfacing_with_the_xpcom_cycle_collector/index.html b/files/zh-cn/mozilla/tech/xpcom/interfacing_with_the_xpcom_cycle_collector/index.html
new file mode 100644
index 0000000000..a0b4472d02
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/interfacing_with_the_xpcom_cycle_collector/index.html
@@ -0,0 +1,141 @@
+---
+title: 与XPCOM cycle collector交互
+slug: Mozilla/Tech/XPCOM/Interfacing_with_the_XPCOM_cycle_collector
+translation_of: Mozilla/Tech/XPCOM/Interfacing_with_the_XPCOM_cycle_collector
+---
+<p>本文是对于在Firefox 3的XPCOM中引入的cycle collector的一个简要描述,描述了将一个已有的C++类修改为一个XPCOM cycle collection中的参与项的步骤。如果你认为你有关于类的循环引用导致的内存泄漏,那可以看看这个。</p>
+
+<p>本文面向Mozilla C++开发者。</p>
+
+<h2 id="What_the_cycle_collector_does" name="What_the_cycle_collector_does">cycle collector干了些什么</h2>
+
+<p>cycle collector大部分时间在记录可能导致循环引用的XPCOM对象指针。在collector的空闲阶段,<code>nsAutoRefCnt的变体通过collector快速的修改自己的注册状态(注册/注销),会传递出一个“可疑”的引用计数事件(从N+1到N,N≠0)。</code></p>
+
+<p>collector会阶段性的唤醒并验证缓冲区中记录过的可疑指针。这是collector的扫描阶段。在这个阶段,collector会请求每个候选项的cycle-collection helper类,如果存在,则需要helper来描述候选项拥有的子结构。collector可以以这种方式建立一个从可疑对象开始的拥有权关系图。</p>
+
+<p>如果collector发现一组对象出现了彼此互相引用,并且确定组内对象的引用计数全由组内其他对象提供,则认定这组对象为循环引用,并尝试释放它们。这是collector的释放阶段。在这个阶段,collector遍历已找到的循环引用对象,再次请求它们的helper对象,释放其子结构和其他对象的引用。</p>
+
+<p>collector也能遍历JS堆,并定位传入和传出的循环引用。</p>
+
+<h2 id="How_the_collector_can_fail" name="How_the_collector_can_fail">collector失效</h2>
+
+<p>cycle collector是一个保守的设备。有些情况下,它无法回收循环引用。</p>
+
+<ol>
+ <li>它默认不怀疑任何指针;对象必须要标记它们自己为可疑对象,一般用<code>nsCycleCollectingAutoRefCnt而不是nsAutoRefCnt。</code></li>
+ <li>它只遍历那些在QI(QueryInterface)时返回helper对象的对象。如果在遍历图的过程中遇到了未知的边,那它会直接放弃这条边,因此每条边都需要被标记为可疑对象,否则找不到环。</li>
+ <li>helper对象中的<code>Traverse<font face="Open Sans, arial, x-locale-body, sans-serif">和</font></code><code>Unlink</code>方法不是魔法,是程序员编码的,如果代码写错了,那collector也还是会崩。</li>
+ <li>collector不知道怎么去搜索一个存在栈中的具有所有权的临时指针,所以将它放在程序的最顶层运行是有必要的。虽然有额外的所有权指针时不会崩,但是它会无法统计已记录的对象的引用计数,这也有可能导致回收失败。</li>
+</ol>
+
+<h2 id="How_to_make_your_classes_participate" name="How_to_make_your_classes_participate">怎么标记一个类为候选项</h2>
+
+<p>cycle collector和你的类之间的接口使用<code>xpcom/base/nsCycleCollector.h中的内容实现直接获取,但是在xpcom/glue/nsCycleCollectionParticipant.h中提供了很多方便的宏用来标记你的类。通常,如果你用nsCOMPtr的mBar和mBaz来修改类nsFoo,可以简化为几个简单的修改:</code></p>
+
+<ol>
+ <li>在nsFoo.h和nsFoo.cpp中包含头文件<code>nsCycleCollectionParticipant.h。</code> </li>
+ <li>在nsFoo.cpp中加一行用于声明nsFoo类是cycle collection的候选项的语句:
+ <pre class="brush: cpp">NS_IMPL_CYCLE_COLLECTION_CLASS(nsFoo)</pre>
+ </li>
+ <li>在nsFoo的定义里,将写有<code>NS_DECL_ISUPPORTS的行修改为</code><code>NS_DECL_CYCLE_COLLECTING_ISUPPORTS</code>.</li>
+ <li>
+ <p><code><font face="Open Sans, arial, x-locale-body, sans-serif">在nsFoo的定义里public部分加一行</font>NS_DECL_CYCLE_COLLECTION_CLASS(nsFoo)。如果nsFoo从多个接口继承而来的话,可以写成NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsFoo, nsIBar),在你QueryInterface nsFoo为nsISSupports时,nsIBar作为接口返回。(我们把nsIBar称为nsFoo的典型ISupport类型。)</code></p>
+ </li>
+ <li>在nsFoo.cpp里接口map处加一行<code>NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsFoo)</code> :
+ <pre class="brush: cpp">NS_INTERFACE_TABLE_HEAD(nsFoo)
+ NS_INTERFACE_TABLE2(nsFoo,
+ nsIBar,
+ nsIBaz)
+ NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsFoo)
+NS_INTERFACE_MAP_END
+</pre>
+ </li>
+ <li>在nsFoo.cpp里把<code>NS_IMPL_ADDREF(nsFoo)</code>修改为<code>NS_IMPL_CYCLE_COLLECTING_ADDREF(nsFoo),同样的修改</code><code>NS_IMPL_RELEASE(nsFoo)</code>为<code>NS_IMPL_CYCLE_COLLECTING_RELEASE(nsFoo)。</code></li>
+ <li><code><font face="Open Sans, arial, x-locale-body, sans-serif">可以在nsFoo.cpp中添加合适的</font>NS_IMPL_CYCLE_COLLECTION_#</code>宏, <code>#是你类中的成员数量。如果nsFoo包含两个成员变量,mBar和mBaz,我们可以写成NS_IMPL_CYCLE_COLLECTION_2(nsFoo, mBar, mBaz)。</code></li>
+</ol>
+
+<p>你的类可能会比这张图的结构更复杂。例如,你的类可能有好几个nsISupport基类,需要使用一些执行消除歧义的* _AMBIGUOUS宏。或者说你的类拥有复杂的所有权结构,这样简单的NS_IMPL_CYCLE_COLLECTION_N宏就低效了;你可能需要手动的实现helper类的<em>Traverse和Unlink方法。即使是这样的情况,也可以使用NS_IMPL_CYCLE_COLLECTION_TRAVERSE_ {BEGIN,END}和NS_IMPL_CYCLE_COLLECTION_UNLINK_ {BEGIN,END}。可以在一些复杂的类中看到实例,例如content/base/src/nsGenericElement.cpp。</em> If your class has tearoffs or is being aggregated by other classes it is important to make the tearoff classes or the outer classes participate in cycle collection too, not doing so could lead to the cycle collector trying to collect the objects too soon.</p>
+
+<h3 id="手动的实现Traverse和Unlink方法">手动的实现<em>Traverse和Unlink方法</em></h3>
+
+<p>每个可能包含循环回收对象的域都需要被传递给cycle collector,以检查通过这些域的循环。</p>
+
+<p>用于Traverse的宏主要是是NS_IMPL_CYCLE_COLLECTION_TRAVERSE:</p>
+
+<p>  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSomeMember)</p>
+
+<p>Unlink同理:</p>
+
+<p>  NS_IMPL_CYCLE_COLLECTION_UNLINK(mSomeMember)</p>
+
+<p>这些宏应当处理各种情况,像指向nsISupports对象的指针或者非nsISupports对象的指针,或者这些指针的数组,当然这些指针都是有引用计数的、被collector记录的指针。</p>
+
+<h3 id="处理JSObject">处理JSObject</h3>
+
+<p>如果你的类需要保存一个指向JSObject的指针,你需要告知cycle collector。像这样操作:</p>
+
+<p>首先,它必须被保存在<code>JS::Heap&lt;JSObject *&gt;域,假如你的类nsFoo有一个域mSomeObj:</code></p>
+
+<pre class="brush: cpp">private:
+ ...
+ JS::Heap&lt;JSObject*&gt; mSomeObj;
+ ...</pre>
+
+<p>当你在JS对象指针中存了东西时,你需要用<code>mozilla::HoldJSObjects来告诉GC遍历它并保持这个对象的存活:</code></p>
+
+<pre class="brush: cpp">...
+mSomeObj = ... ;
+<code>mozilla::HoldJSObjects</code>(this);
+...
+</pre>
+
+<p>在Unlink方法(或者析构函数)里,需要将对象指针置为空:</p>
+
+<pre class="brush: cpp">NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsFoo)
+ ...
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mSomeMember)
+  ...
+  //如果你的类是wrapper cache:
+ //NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+
+  tmp-&gt;mSomeObj = nullptr;
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+</pre>
+
+<p>在析构函数里调用</p>
+
+<pre class="brush: cpp"><code>mozilla::DropJSObjects</code>(this);</pre>
+
+<p>你需要在Traverse方法列出cycle collector中记录的成员,也就是非JS对象:</p>
+
+<pre class="brush: cpp">NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsFoo)
+ ...
+ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSomeMember)
+ ...
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+</pre>
+
+<p>最后你需要把JS对象加入Trace方法:</p>
+
+<pre class="brush: cpp">NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsFoo)
+  //if your class is a wrapper cache:
+ //NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
+
+  NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mSomeObj)
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
+</pre>
+
+<p>如果你的类是一个wrapper cache,可能生成的代码用了<code>NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_#</code>宏而不是<code>NS_IMPL_CYCLE_COLLECTION_#</code>. 这个宏不能定义Trace方法,因此不能列出JS对象;所以你需要向上面那样手动实现Trace和Unlink。</p>
+
+<h3 id="处理_JSValue_fields">处理 JS::Value fields</h3>
+
+<p> <a href="/en-US/docs/SpiderMonkey/JSAPI_Reference/Jsval" title="/en-US/docs/SpiderMonkey/JSAPI_Reference/Jsval">这里</a>说过,一个<code>JS::Value可能引用一个字符串或者对象并且被GC控制。于是我们需要告知cycle collector这种成员变量的存在。这与JSObject相似,但是使用的是NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK宏:</code></p>
+
+<pre class="brush: cpp">NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsFoo)
+ ...
+ NS_IMPL_CYCLE_COLLECTION_TRACE_JSVAL_MEMBER_CALLBACK(mSomeJSVal).
+ ...
+NS_IMPL_CYCLE_COLLECTION_TRACE_END
+</pre>
+
+<p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/language_bindings/components.utils.cloneinto/index.html b/files/zh-cn/mozilla/tech/xpcom/language_bindings/components.utils.cloneinto/index.html
new file mode 100644
index 0000000000..0bc55dbf99
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/language_bindings/components.utils.cloneinto/index.html
@@ -0,0 +1,290 @@
+---
+title: Components.utils.cloneInto
+slug: Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.cloneInto
+translation_of: Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.cloneInto
+---
+<div><section class="Quick_links" id="Quick_Links">
+ <ol>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions"><strong>Browser extensions</strong></a></li>
+ <li class="toggle">
+ <details>
+ <summary>Getting started</summary>
+ <ol>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/What_are_WebExtensions">What are extensions?</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Your_first_WebExtension">Your first extension</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Your_second_WebExtension">Your second extension</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension">Anatomy of an extension</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Examples">Example extensions</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/What_next_">What next?</a></li>
+ </ol>
+ </details>
+ </li>
+ <li class="toggle">
+ <details>
+ <summary>Concepts</summary>
+ <ol>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Using_the_JavaScript_APIs">Using the JavaScript APIs</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Content_scripts">Content scripts</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Match_patterns">Match patterns</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Working_with_files">Working with files</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Internationalization">Internationalization</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Security_best_practices">Security best practices</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Content_Security_Policy">Content Security Policy</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Native_messaging">Native messaging</a></li>
+ </ol>
+ </details>
+ </li>
+ <li class="toggle">
+ <details>
+ <summary>User interface</summary>
+ <ol>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/user_interface">User Interface</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/user_interface/Browser_action">Toolbar button</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/user_interface/Page_actions">Address bar button</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/user_interface/Sidebars">Sidebars</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/user_interface/Context_menu_items">Context menu items</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/user_interface/Options_pages">Options page</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/user_interface/Extension_pages">Extension pages</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/user_interface/Notifications">Notifications</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/user_interface/Omnibox">Address bar suggestions</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/user_interface/devtools_panels">Developer tools panels</a></li>
+ </ol>
+ </details>
+ </li>
+ <li class="toggle">
+ <details>
+ <summary>How to</summary>
+ <ol>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Intercept_HTTP_requests">Intercept HTTP requests</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Modify_a_web_page">Modify a web page</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Safely_inserting_external_content_into_a_page">Insert external content</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Add_a_button_to_the_toolbar">Add a button to the toolbar</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Implement_a_settings_page">Implement a settings page</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Working_with_the_Tabs_API">Work with the Tabs API</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Work_with_the_Bookmarks_API">Work with the Bookmarks API</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Work_with_the_Cookies_API">Work with the Cookies API</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Work_with_contextual_identities">Work with contextual identities</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/onboarding_upboarding_offboarding_best_practices">Onboard, upboard, and offboard users</a></li>
+ </ol>
+ </details>
+ </li>
+ <li class="toggle">
+ <details>
+ <summary>Porting</summary>
+ <ol>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Firefox_differentiators">Firefox differentiators</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Porting_a_Google_Chrome_extension">Porting a Google Chrome extension</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Porting_a_legacy_Firefox_add-on">Porting a legacy Firefox extension</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Embedded_WebExtensions">Embedded WebExtensions</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Comparison_with_the_Add-on_SDK">Comparison with the Add-on SDK</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Comparison_with_XUL_XPCOM_extensions">Comparison with XUL/XPCOM extensions</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Differences_between_API_implementations">Differences between API implementations</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities">Chrome incompatibilities</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Differences_between_desktop_and_Android">Differences between desktop and Android</a></li>
+ </ol>
+ </details>
+ </li>
+ <li class="toggle">
+ <details>
+ <summary>Firefox workflow</summary>
+ <ol>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Development_Tools">Developer tools</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/User_experience_best_practices">User Experience</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Temporary_Installation_in_Firefox">Temporary Installation in Firefox</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Debugging">Debugging</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Testing_persistent_and_restart_features">Testing persistent and restart features</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Developing_WebExtensions_for_Firefox_for_Android">Developing for Firefox for Android</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Getting_started_with_web-ext">Getting started with web-ext</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/web-ext_command_reference">web-ext command reference</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/WebExtensions_and_the_Add-on_ID">Extensions and the Add-on ID</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Request_the_right_permissions">Request the right permissions</a></li>
+ </ol>
+ </details>
+ </li>
+ <li class="toggle">
+ <details>
+ <summary>JavaScript APIs</summary>
+ <ol><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Browser_support_for_JavaScript_APIs">Browser support for JavaScript APIs</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/alarms">alarms</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/bookmarks">bookmarks</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/browserAction">browserAction</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/contextMenus">contextMenus</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/cookies">cookies</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/devtools.inspectedWindow">devtools.inspectedWindow</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/history">history</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/runtime">runtime</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/storage">storage</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/tabs">tabs</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/webNavigation">webNavigation</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/webRequest">webRequest</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/windows">windows</a></li></ol>
+ </details>
+ </li>
+
+ <li class="toggle">
+ <details>
+ <summary>Manifest keys</summary>
+ <ol><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings">applications</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_action">browser_action</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_scripts">content_scripts</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json/default_locale">default_locale</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json/developer">developer</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json/manifest_version">manifest_version</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json/version">version</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json/%E4%B8%BB%E9%A1%B5%E5%9C%B0%E5%9D%80">主页地址</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json/author">作者 - author</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json/name">名称 - name</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json/background">后台 - background</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json/description">描述 - description</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions">权限 - permissions</a></li><li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json/short_name">短名称 - short_name</a></li></ol>
+ </details>
+ </li>
+
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/Themes"><strong>Themes</strong></a></li>
+ <li class="toggle">
+ <details>
+ <summary>Browser themes</summary>
+ <ol>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/Themes/Theme_concepts">Browser theme concepts</a></li>
+ </ol>
+ </details>
+ </li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/Distribution"><strong>Publishing and Distribution</strong></a></li>
+ <li class="toggle">
+ <details>
+ <summary>Publishing add-ons</summary>
+ <ol>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/Distribution">Signing and distribution overview</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Package_your_extension_">Package your extension</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/Distribution/Submitting_an_add-on">Submit an add-on</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/Source_Code_Submission">Source code submission</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/Distribution/Resources_for_publishers">Resources for publishers</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/Listing">Creating an appealing listing</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/Distribution/Make_money_from_browser_extensions">Make money from browser extensions</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/Distribution/Promoting_your_extension_or_theme">Promoting your extension or theme</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/AMO/Policy/Reviews">Review policies</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/AMO/Policy/Agreement">Developer agreement</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/AMO/Policy/Featured">Featured add-ons</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/Distribution/Retiring_your_extension">Retiring your extension</a></li>
+ </ol>
+ </details>
+ </li>
+ <li class="toggle">
+ <details>
+ <summary>Distributing add-ons</summary>
+ <ol>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Alternative_distribution_options/Sideloading_add-ons">For sideloading</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Alternative_distribution_options/Add-ons_for_desktop_apps">For desktop apps</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Alternative_distribution_options/Add-ons_in_the_enterprise">For an enterprise</a></li>
+ </ol>
+ </details>
+ </li>
+ <li><a href="https://discourse.mozilla.org/c/add-ons"><strong>Community and Support</strong></a></li>
+ <li class="toggle">
+ <details>
+ <summary>Channels</summary>
+ <ol>
+ <li><a href="https://blog.mozilla.org/addons">Add-ons blog</a></li>
+ <li><a href="https://discourse.mozilla.org/c/add-ons">Add-on forums</a></li>
+ <li><a href="http://stackoverflow.com/questions/tagged/firefox-addon">Stack Overflow</a></li>
+ <li><a href="/zh-CN/docs/Mozilla/Add-ons/#Contact_us">Contact us</a></li>
+ </ol>
+ </details>
+ </li>
+ </ol>
+</section></div>
+
+<p><span class="seoSummary">该函数为定义在某一作用域中的对象提供了一个安全的、将其<a href="https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/The_structured_clone_algorithm">结构化克隆</a>到其字作用域中的方法,</span>并返回对克隆对象的引用:</p>
+
+<pre class="brush: js">var clonedObject = cloneInto(myObject, targetWindow);</pre>
+
+<p>可以将克隆后的对象作为可扩展对象的动态属性引入到特定作用域中,以便运行在该作用域的脚本进行访问:</p>
+
+<pre class="brush: js">targetWindow.foo = clonedObject;</pre>
+
+<p>通过这种方式,运行在某一作用域中的代码可以和运行在另一作用域中的代码共享对某一对象的访问。</p>
+
+<h2 id="语法">语法</h2>
+
+<pre class="brush: js">Components.utils.cloneInto(obj, targetScope[, options]);</pre>
+
+<h3 id="参数列表">参数列表</h3>
+
+<dl>
+ <dt><code>obj : object</code></dt>
+ <dd>被克隆对象。</dd>
+ <dt><code>targetScope : object</code></dt>
+ <dd>对象克隆后的容器。</dd>
+ <dt><code>options : object</code></dt>
+ <dd>该参数为一可选参数。该参数为一拥有以下可选属性的对象:</dd>
+</dl>
+
+<ul>
+ <li><code>cloneFunctions</code>: 决定函数是否被克隆的布尔值。默认值为 <code>false</code>。Cloned functions have the same semantics as functions exported using <a href="/en-US/docs/Components.utils.exportFunction"><code>Components.utils.exportFunction</code></a>. See <a href="/en-US/docs/Components.utils.cloneInto#Cloning_objects_that_have_functions">Cloning objects that have functions</a> below.</li>
+ <li><code>wrapReflectors</code>: a Boolean value that determines if objects reflected from C++, such as DOM objects, should be cloned. If omitted the default value is <code>false</code>. See <a href="/en-US/docs/Components.utils.cloneInto#Cloning_objects_that_contain_DOM_elements">Cloning objects that contain DOM elements</a> below.</li>
+</ul>
+
+<h3 id="返回值">返回值</h3>
+
+<p>对克隆后的对象的引用。</p>
+
+<h2 id="范例">范例</h2>
+
+<p>This add-on script creates an object, clones it into the content window and makes it a property of the content window global:</p>
+
+<pre class="brush: js">// add-on script
+
+var addonScriptObject = {"greeting" : "hello from add-on"};
+contentWindow.addonScriptObject = cloneInto(addonScriptObject, contentWindow);</pre>
+
+<p>Scripts running in the page can now access the object:</p>
+
+<pre class="brush: js">// page script
+
+button.addEventListener("click", function() {
+ console.log(window.addonScriptObject.greeting); // "hello from add-on"
+}, false);</pre>
+
+<p>Of course, you don't have to assign the clone to the window itself: you can assign it to some other object in the target scope:</p>
+
+<pre class="brush: js">contentWindow.foo.addonScriptObject = cloneInto(addonScriptObject, contentWindow);</pre>
+
+<p>You can also pass it into a function defined in the page script. Suppose the page script defines a function like this:</p>
+
+<pre class="brush: js">// page script
+
+function foo(greeting) {
+ console.log("they said: " + greeting.message);
+}
+</pre>
+
+<p>The add-on script can define an object, clone it, and pass it into this function:</p>
+
+<pre class="brush: js">// add-on script
+
+var addonScriptObject = {"message" : "hello from add-on"};
+contentWindow.foo(cloneInto(addonScriptObject, contentWindow)); // "they said: hello from add-on"</pre>
+
+<h3 id="Cloning_objects_that_have_functions">Cloning objects that have functions</h3>
+
+<p>If the object to be cloned contains functions, you must pass the <code>{cloneFunctions:true}</code> flag or you'll get an error. If you do pass this flag, then functions in the object are cloned using the same mechanism as that used in <a href="/en-US/docs/Components.utils.exportFunction"><code>Components.utils.exportFunction</code></a>:</p>
+
+<pre class="brush: js">// add-on script
+
+var addonScriptObject = {
+ greetme: function() {
+ alert("hello from add-on");
+ }
+};
+
+contentWindow.addonScriptObject = cloneInto(addonScriptObject,
+ contentWindow,
+ {cloneFunctions: true});
+</pre>
+
+<pre class="brush: js">// page script
+
+var test = document.getElementById("test");
+
+test.addEventListener("click", function() {
+ window.addonScriptObject.greetme();
+}, false);</pre>
+
+<h3 id="Cloning_objects_that_contain_DOM_elements">Cloning objects that contain DOM elements</h3>
+
+<p>By default, if the object you clone contains objects that are reflected from C++, such as DOM elements, the cloning operation will fail with an error. If you pass the <code>{wrapReflectors:true}</code> flag, then the object you clone is allowed to contain these objects:</p>
+
+<pre class="brush: js">// add-on script
+
+var addonScriptObject = {
+ body: contentWindow.document.body
+};
+
+contentWindow.addonScriptObject = cloneInto(addonScriptObject,
+ contentWindow,
+ {wrapReflectors: true});</pre>
+
+<pre class="brush: js">// page script
+
+var test = document.getElementById("test");
+
+test.addEventListener("click", function() {
+ console.log(window.addonScriptObject.body.innerHTML);
+}, false);</pre>
+
+<p>Access to these objects in the target scope is subject to the normal <a href="/en-US/docs/Security_check_basics">security checks</a>.</p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/language_bindings/components.utils.getglobalforobject/index.html b/files/zh-cn/mozilla/tech/xpcom/language_bindings/components.utils.getglobalforobject/index.html
new file mode 100644
index 0000000000..a22b49a2d5
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/language_bindings/components.utils.getglobalforobject/index.html
@@ -0,0 +1,41 @@
+---
+title: Components.utils.getGlobalForObject
+slug: Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.getGlobalForObject
+translation_of: Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.getGlobalForObject
+---
+<p></p>
+
+<p><font>此方法是用于确定与对象关联的全局对象。用于</font>获取创建对象时所处的全局对象, 即在执行创建对象的脚本时使用的全局对象。</p>
+
+<h3 id="Syntax" name="Syntax">语法</h3>
+
+<pre class="eval">var global = Components.utils.getGlobalForObject(<em>obj</em>);
+</pre>
+
+<h3 id="Parameters" name="Parameters">参数</h3>
+
+<dl>
+ <dt><code>obj</code></dt>
+ <dd>其对应的全局对象将被检索的对象; 非可选参数,必须是对象。</dd>
+</dl>
+
+<h3 id="Example" name="Example">例子</h3>
+
+<pre class="eval">var obj = {};
+function foo() { }
+var global = this;
+
+var g1 = Components.utils.getGlobalForObject(foo);
+var g2 = Components.utils.getGlobalForObject(obj);
+// g1 === global, g2 === global, g1 === g2
+
+// In a script in another window
+var global2 = this;
+function bar() { }
+var obj2 = {};
+
+// Then, assuming bar refers to the function defined in that other window:
+var o1 = Components.utils.getGlobalForObject(bar);
+var o2 = Components.utils.getGlobalForObject(obj2);
+// o1 === global2, o2 === global2
+</pre>
diff --git a/files/zh-cn/mozilla/tech/xpcom/language_bindings/index.html b/files/zh-cn/mozilla/tech/xpcom/language_bindings/index.html
new file mode 100644
index 0000000000..cf8ced2678
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/language_bindings/index.html
@@ -0,0 +1,20 @@
+---
+title: 语言绑定
+slug: Mozilla/Tech/XPCOM/Language_Bindings
+tags:
+ - XPCOM
+ - 'XPCOM:Language Bindings'
+translation_of: Mozilla/Tech/XPCOM/Language_Bindings
+---
+<p>一款 <strong>XPCOM 的语言绑定</strong>是连接某种特定的程序设计语言与 <a href="/cn/XPCOM" title="cn/XPCOM">XPCOM</a> 之间的纽带,它用来提供从语言到 XPCOM 对象的访问, 并且将此种语言写成的模块作为其他进行 XPCOM 绑定的程序语言的 XPCOM 对象。 </p>
+<p>更具体的说, 一个 XPCOM 语言绑定:</p>
+<ul>
+ <li>允许<em>在特定的程序设计语言中访问 XPCOM 对象</em>(此处,访问的意思是能够读取、写入和创建 XPCOM 对象以及调用这些对象的方法)。</li>
+ <li>暴露<em>由</em><em>特定的程序设计语言</em><em>编写的模块并使之成为一个 XPCOM 对象</em>,从而允许所有已绑定的其它程序设计语言能够访问这些模块。</li>
+</ul>
+<p>由于 XPCOM 层本身使用 C/C++ 编写,因此可以使用 C/C++ 直接访问其 API。而当其它的程序设计语言需要访问该 API 时,则需要通过额外的桥接层来实现。</p>
+<p>当前有效的链接层如下:</p>
+<p></p><div class="row topicpage-table">
+ <div class="section"><dl><dl><dt class="landingPageList"><a href="/zh-CN/docs/Components_object">Components</a></dt><dd class="landingPageList"><code>Components</code> 对象是 <a href="https://developer.mozilla.org/en/XPConnect" title="en/XPConnect">XPConnect</a> 功能被映射到 <a href="https://developer.mozilla.org/en/JavaScript" title="en/JavaScript">JavaScript</a> 上的对象。<code>Components</code> 对象的 native 实现位置在   <a href="https://dxr.mozilla.org/mozilla-central/source/js/xpconnect/idl/xpccomponents.idl" rel="custom">nsIXPCComponents</a> , 这个接口会被映射成JavaScript 作为使用 XPConnect 的最高层级的对象。</dd><dt class="landingPageList"><a href="/zh-CN/docs/Components.classes">Components.classes</a></dt><dd class="landingPageList"></dd><dt class="landingPageList"><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.cloneInto">Components.utils.cloneInto</a></dt><dd class="landingPageList">该函数为定义在某一作用域中的对象提供了一个安全的、将其<a href="https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/The_structured_clone_algorithm">结构化克隆</a>到其字作用域中的方法,</dd><dt class="landingPageList"><a href="/zh-CN/docs/Components.utils.evalInSandbox">Components.utils.evalInSandbox</a></dt><dd class="landingPageList"></dd><dt class="landingPageList"><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.getGlobalForObject">Components.utils.getGlobalForObject</a></dt><dd class="landingPageList"><font>此方法是用于确定与对象关联的全局对象。用于</font>获取创建对象时所处的全局对象, 即在执行创建对象的脚本时使用的全局对象。</dd></dl></dl></div>
+ <div class="section"><dl><dt class="landingPageList"><a href="/zh-CN/docs/Components.utils.import">Components.utils.import</a></dt><dd class="landingPageList">这个方法在 <a href="/en/Firefox_3_for_developers" title="en/Firefox_3_for_developers">Firefox 3</a> 中被引入,它使得在不同的作用域之间分享代码变得更加容易。例如:你可以直接导入 <a href="/en/JavaScript_code_modules/XPCOMUtils.jsm" title="en/XPCOMUtils.jsm">XPCOMUtils.jsm</a> 而不必复制/粘贴冗长的XPCOM组件。</dd><dt class="landingPageList"><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Language_bindings/JavaXPCOM">JavaXPCOM</a></dt><dd class="landingPageList"></dd><dt class="landingPageList"><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Language_bindings/PyXPCOM">PyXPCOM</a></dt><dd class="landingPageList"></dd><dt class="landingPageList"><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Language_bindings/XPConnect">XPConnect</a></dt><dd class="landingPageList">[<a class="external" href="http://developer.mozilla.org/en/docs/XPConnect">] </a></dd></dl></div>
+ </div><p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/index.html b/files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/index.html
new file mode 100644
index 0000000000..6ce4c6a6ba
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/index.html
@@ -0,0 +1,49 @@
+---
+title: JavaXPCOM
+slug: Mozilla/Tech/XPCOM/Language_bindings/JavaXPCOM
+tags:
+ - Java
+ - JavaXPCOM
+translation_of: Mozilla/Tech/XPCOM/Language_bindings/JavaXPCOM
+---
+<p>
+</p><p><b>JavaXPCOM</b>允许在Java和<a href="cn/XPCOM">XPCOM</a>间进行会话,这样一来,Java应用程序就可以访问XPCOM对象,并且XPCOM也可以访问任何实现了XPCOM接口的Java类。借助JavaXPCOM,开发者可以在Java应用程序中同XPCOM或嵌入的<a href="cn/Gecko">Gecko</a>对话。JavaXPCOM和<a href="cn/XPConnect">XPConnect</a>(JavaScript-XPCOM桥)十分相似,并且使用<a href="cn/XPIDL">XPIDL</a>实现其功能。
+</p><p>JavaXPCOM默认地作为<a href="cn/XULRunner">XULRunner</a>的一部分被构建。下载最近的编译成品或<a href="cn/XULRunner_1.8.0.4">XULRunner 1.8.0.4</a>进行尝试。
+</p>
+<table class="topicpage-table">
+<tbody><tr><td>
+<h4 id=".E9.A2.84.E8.A7.88" name=".E9.A2.84.E8.A7.88"> 预览 </h4>
+<ul><li> <a href="cn/JavaXPCOM/%e5%bc%80%e5%8f%91">JavaXPCOM:开发</a>
+</li><li> <a href="cn/JavaXPCOM/%e8%8c%83%e4%be%8b">JavaXPCOM:范例</a>
+</li></ul>
+<h4 id=".E6.96.87.E7.AB.A0.E7.B2.BE.E9.80.89" name=".E6.96.87.E7.AB.A0.E7.B2.BE.E9.80.89"> 文章精选 </h4>
+<ul><li> <a href="cn/JavaXPCOM/%e4%bd%bf%e7%94%a8JavaXPCOM%e5%9c%a8Java%e5%ba%94%e7%94%a8%e7%a8%8b%e5%ba%8f%e4%b8%ad%e5%b5%8c%e5%85%a5Mozilla">JavaXPCOM:使用JavaXPCOM在Java应用程序中嵌入Mozilla</a>
+</li></ul>
+<p><span class="alllinks"><a>View All...</a></span>
+</p>
+</td>
+<td>
+<h4 id=".E5.85.B6.E4.BB.96.E9.A1.B5.E9.9D.A2" name=".E5.85.B6.E4.BB.96.E9.A1.B5.E9.9D.A2"> 其他页面 </h4>
+<ul><li> <a>参考</a>
+</li><li> <a>文章</a>
+</li><li> <a>范例</a>
+</li><li> <a href="cn/JavaXPCOM/Community">社区</a>
+</li><li> <a href="cn/JavaXPCOM/Other_Resources">其他资源</a>
+</li></ul>
+<h4 id=".E7.9B.B8.E5.85.B3.E4.B8.BB.E9.A2.98" name=".E7.9B.B8.E5.85.B3.E4.B8.BB.E9.A2.98"> 相关主题 </h4>
+<dl><dd> <a href="cn/XPCOM">XPCOM</a>, <a href="cn/Embedding_Mozilla">嵌入式Mozilla</a>
+</dd></dl>
+<p><span class="comment">there's no javaxpcom category on webwatch &lt;rss&gt;<a class=" external" href="http://developer.mozilla.org/webwatch/?cat=23&amp;feed=rss2" rel="freelink">http://developer.mozilla.org/webwatc...t=23&amp;feed=rss2</a>|short|max=5|charset=UTF-8&lt;/rss&gt; &lt;span class="alllinks"&gt;<a class="external" href="http://developer.mozilla.org/webwatch/?cat=23" title="http://developer.mozilla.org/webwatch/?cat=23">View All...</a>&lt;/span&gt;</span>
+</p>
+</td>
+</tr>
+</tbody></table>
+<div class="originaldocinfo">
+<h2 id=".E5.8E.9F.E5.A7.8B.E6.96.87.E6.A1.A3.E4.BF.A1.E6.81.AF" name=".E5.8E.9F.E5.A7.8B.E6.96.87.E6.A1.A3.E4.BF.A1.E6.81.AF">原始文档信息</h2>
+<ul><li> 作者: <a class="link-mailto" href="mailto:jhpedemonte@gmail.com">Javier Pedemonte</a>
+</li><li> 最后更新: December 22, 2005
+</li><li> 版权信息: Copyright (C) <a class="link-mailto" href="mailto:jhpedemonte@gmail.com">Javier Pedemonte</a>
+</li></ul>
+</div>
+<p><br>
+</p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/使用javaxpcom在java应用程序中嵌入mozilla/index.html b/files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/使用javaxpcom在java应用程序中嵌入mozilla/index.html
new file mode 100644
index 0000000000..9a8e1805fa
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/使用javaxpcom在java应用程序中嵌入mozilla/index.html
@@ -0,0 +1,65 @@
+---
+title: 使用JavaXPCOM在Java应用程序中嵌入Mozilla
+slug: Mozilla/Tech/XPCOM/Language_bindings/JavaXPCOM/使用JavaXPCOM在Java应用程序中嵌入Mozilla
+tags:
+ - 'JavaXPCOM:Articles'
+translation_of: Archive/Mozilla/Embedding_Mozilla_in_a_Java_Application_using_JavaXPCOM
+---
+<p>
+</p><p><br>
+<a href="cn/XULRunner">XULRunner</a>中包含了<a href="cn/JavaXPCOM">JavaXPCOM</a>组件,允许Java代码与XPCOM对象交互。在这片文章中您将会看到,在Java中使用XPCOM对象,要比在C++中容易得多。
+</p>
+<h4 id=".E5.BF.85.E8.A6.81.E6.9D.A1.E4.BB.B6" name=".E5.BF.85.E8.A6.81.E6.9D.A1.E4.BB.B6"> 必要条件 </h4>
+<ul><li> Java 1.4.2或者更新
+</li><li> XULRunner
+</li></ul>
+<div class="note">
+<p><b>2006-01-16</b>:XULRunner目前还没有官方发布版本,因此,为了能XULRunner加上JavaXPCOM一起使用,您应该马上下载1.8.0版分支的一个每夜构建。(<a class="external" href="http://ftp.mozilla.org/pub/mozilla.org/xulrunner/nightly/latest-mozilla1.8.0/xulrunner-1.8.0.1.en-US.linux-i686.tar.gz">Linux</a>,<a class="external" href="http://ftp.mozilla.org/pub/mozilla.org/xulrunner/nightly/latest-mozilla1.8.0/xulrunner-1.8.0.1.en-US.mac.dmg">Mac OS X</a>,<a class="external" href="http://ftp.mozilla.org/pub/mozilla.org/xulrunner/nightly/latest-mozilla1.8.0/xulrunner-1.8.0.1.en-US.win32.zip">Windows</a>)。下面提到的<i>MozillaInterfaces.jar</i>文件可以在<i>sdk</i>顶层文件夹中找到。
+</p>
+</div>
+<h4 id=".E5.B5.8C.E5.85.A5" name=".E5.B5.8C.E5.85.A5"> 嵌入 </h4>
+<p>为了在Java应用程序中嵌入Mozilla,您需要将库文件<i>MozillaInterfaces.jar</i>加入您的classpath中。这个库(它是SDK的一部分)提供了启动Mozilla和调用XPCOM方法所必需的接口。
+</p><p>要开始嵌入,我们使用<a href="https://dxr.mozilla.org/mozilla-central/source/extensions/java/xpcom/interfaces/Mozilla.java" rel="custom">Mozilla</a>单件类提供的方法。首先,Java应用程序必须找到一个合适的XULRunner安装:
+</p>
+<pre class="eval"> Mozilla mozilla = Mozilla.getInstance();
+ GREVersionRange[] range = new GREVersionRange[1];
+ range[0] = new GREVersionRange("1.8.*", false, "1.9", false);
+ <span class="highlightgreen">// work with trunk nightly version 1.9a1 ^^</span>
+
+ try {
+ File grePath = Mozilla.getGREPathWithProperties(range, null);
+ LocationProvider locProvider = new LocationProvider(grePath);
+ mozilla.initEmbedding(grePath, grePath, locProvider);
+ } catch (FileNotFoundException e) {
+ <span class="highlightgreen">// this exception is thrown if greGREPathWithProperties cannot find a GRE</span>
+ } catch (XPCOMException e) {
+ <span class="highlightgreen">// this exception is thrown if initEmbedding failed</span>
+ }
+</pre>
+<p><code>LocationProvider</code>是Java应用程序提供的一个类。它实现了<a href="https://dxr.mozilla.org/mozilla-central/source/extensions/java/xpcom/interfaces/IAppFileLocProvider.java" rel="custom">IAppFileLocProvider</a>接口,并且告诉XPCOM那里可以找到那些文件和目录。
+</p><p><code>initEmbedding</code>方法启动嵌入进程,允许Java应用程序与XPCOM和Mozilla一起工作。一旦Java应用程序使用完Mozilla,就需要中止嵌入进程:
+</p>
+<pre class="eval"> try {
+ mozilla.termEmbedding();
+ } catch (XPCOMException e) {
+ <span class="highlightgreen">// this exception is thrown if termEmbedding failed</span>
+ }
+</pre>
+<h4 id=".E4.B8.8EXPCOM.E5.AF.B9.E8.B1.A1.E4.B8.80.E8.B5.B7.E5.B7.A5.E4.BD.9C" name=".E4.B8.8EXPCOM.E5.AF.B9.E8.B1.A1.E4.B8.80.E8.B5.B7.E5.B7.A5.E4.BD.9C"> 与XPCOM对象一起工作 </h4>
+<p>现在,Mozilla已经嵌入了,Java应用程序可以和XPCOM对象工作了。<code>Mozilla</code>类提供了多种方法使工作更加容易,例如<code>getServiceManager</code>,<code>getComponentManager</code>,和<code>newLocalFile</code>。为了在XPCOM对象中增加查询和调用的方法,JavaXPCOM允许Java应用程序传递Java类对象给XPCOM方法。
+</p><p>例如:
+</p>
+<pre class="eval"> Mozilla mozilla = Mozilla.getInstance();
+ WindowCreator creator = new WindowCreator(); <span class="highlightgreen">// implements nsIWindowCreator</span>
+
+ nsIServiceManager serviceManager = mozilla.getServiceManager();
+
+ nsIWindowWatcher windowWatcher = (nsIWindowWatcher) serviceManager
+ .getServiceManagerByContractID(NS_WINDOWWATCHER_CONTRACTID,
+ nsIWindowWatcher.NS_IWINDOWWATCHER_IID);
+ windowWatcher.setWindowCreator(creator);
+</pre>
+<p>在这个例子中,我们有一个叫<code>WindowCreator</code>的类,它实现了<code>nsIWindowCreator</code>接口,我们想要在Mozilla中注册它。要做到这点,我们首先获取服务管理器(service manager),通过它,我们可以获取Mozilla窗口监视器的引用。
+</p>
+<div class="noinclude">
+</div>
diff --git a/files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/开发/index.html b/files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/开发/index.html
new file mode 100644
index 0000000000..d21deddbb6
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/language_bindings/javaxpcom/开发/index.html
@@ -0,0 +1,26 @@
+---
+title: 开发
+slug: Mozilla/Tech/XPCOM/Language_bindings/JavaXPCOM/开发
+tags:
+ - JavaXPCOM
+translation_of: Mozilla/Tech/XPCOM/Language_bindings/JavaXPCOM/Development
+---
+<p>
+</p>
+<h3 id=".E7.AE.80.E8.BF.B0" name=".E7.AE.80.E8.BF.B0"> 简述 </h3>
+<p>JavaXPCOM源于Mozilla的Java版firefox计划,后来演变为Mozilla的一项重要的扩展应用技术。目前JavaXPCOM是Mozilla最活跃的扩展应用技术之一。
+简单的说,JavaXPCOM就是通过Java运行环境启动GRE(Gecko Runtime Environment)环境,然后通过Java Interface与GRE typelib的映射关系,使得Java对象可以与XPCOM对象进行对象交互。当然,与XPCOM一样,JavaXPCOM也支持通过XPConnect映射同以xul/js为主体的Mozilla界面环境进行对象交互。
+</p>
+<h3 id=".E6.BA.90.E4.BB.A3.E7.A0.81" name=".E6.BA.90.E4.BB.A3.E7.A0.81"> 源代码 </h3>
+<p>最新的源代码可以在Mozilla主干上找到,在<code><a href="https://dxr.mozilla.org/mozilla-central/source/extensions/java/xpcom" rel="custom">extensions/java/xpcom</a></code>目录中。
+</p>
+<h3 id=".E6.9E.84.E5.BB.BA.E6.8C.87.E4.BB.A4" name=".E6.9E.84.E5.BB.BA.E6.8C.87.E4.BB.A4"> 构建指令 </h3>
+<p>构建指令可以在这里找到:<a href="cn/%e6%9e%84%e5%bb%baJavaXPCOM">构建JavaXPCOM</a>。
+</p>
+<h3 id="Bugs" name="Bugs"> Bugs </h3>
+<p>所有的JavaXPCOM的bugs都在<a class="external" href="http://bugzilla.mozilla.org/">Bugzilla</a>中被跟踪, 使用"Core"产品和"Java to XPCOM Bridge"组件。
+</p>
+<ul><li> <a class="link-https" href="https://bugzilla.mozilla.org/buglist.cgi?query_format=advanced&amp;product=Core&amp;component=Java+to+XPCOM+Bridge&amp;bug_status=UNCONFIRMED&amp;bug_status=NEW&amp;bug_status=ASSIGNED&amp;bug_status=REOPENED&amp;chfieldto=Now">List</a>共开的JavaXPCOM bugs
+</li><li> <a class="link-https" href="https://bugzilla.mozilla.org/enter_bug.cgi?product=Core&amp;component=Java+to+XPCOM+Bridge&amp;rep_platform=All&amp;op_sys=All">Open</a> 一个新的JavaXPCOM的bug
+</li><li> <a class="external" href="http://bonsai.mozilla.org/cvsquery.cgi?treeid=default&amp;module=all&amp;branch=HEAD&amp;branchtype=match&amp;dir=mozilla%2Fextensions%2Fjava%2Fxpcom&amp;file=&amp;filetype=match&amp;who=&amp;whotype=match&amp;sortby=Date&amp;hours=2&amp;date=month&amp;mindate=&amp;maxdate=&amp;cvsroot=%2Fcvsroot">Checkins</a> 最近一个月之内
+</li></ul>
diff --git a/files/zh-cn/mozilla/tech/xpcom/language_bindings/pyxpcom/index.html b/files/zh-cn/mozilla/tech/xpcom/language_bindings/pyxpcom/index.html
new file mode 100644
index 0000000000..397d95ff78
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/language_bindings/pyxpcom/index.html
@@ -0,0 +1,67 @@
+---
+title: PyXPCOM
+slug: Mozilla/Tech/XPCOM/Language_bindings/PyXPCOM
+translation_of: Mozilla/Tech/XPCOM/Language_bindings/PyXPCOM
+---
+<p> </p>
+<div>
+ <p><strong>PyXPCOM</strong>允许在<a href="http://www.python.org/" title="http://www.python.org/">Python</a>和<a href="/en/XPCOM" title="/en/XPCOM">XPCOM</a>之间进行通信,例如Python应用能够访问XPCOM对象,XPCOM能够访问任何实现了XPCOM接口的Python类。使用PyXPCOM一个开发者可以与XPCOM交互或者从一个Python应用中嵌入<a href="/en/Gecko" title="/en/Gecko">Gecko</a>。PyXPCOM就类似于<a href="/en/JavaXPCOM" title="/en/JavaXPCOM">JavaXPCOM</a>(Java-XPCOM桥)或者是<a href="/en/XPConnect" title="/en/XPConnect">XPConnect</a>(JavaScript-XPCOM桥)。</p>
+ <p>Python类和接口:Mozilla定义了许多外部接口并允许用于嵌入使用和组件开发。PyXPCOM提供了方法以像Python语言接口那样来访问这些接口。PyXPCOM同时也包含了几个用于提供从Python访问那些初始化及关闭XPCOM和Gecko功能的类,以及一些XPCOM的帮助函数。</p>
+</div>
+<table class="topicpage-table">
+ <tbody>
+ <tr>
+ <td>
+ <h4 id="Documentation" name="Documentation"><a href="/Special:Tags?tag=PyXPCOM&amp;language=en" title="Special:Tags?tag=PyXPCOM&amp;language=en">文档</a></h4>
+ <dl>
+ <dt>
+ <a href="/zh-CN/docs/Building_PyXPCOM" title="en/Building_PyXPCOM">构建 PyXPCOM</a></dt>
+ <dd>
+ <small>PyXPCOM</small>构建指导。</dd>
+ </dl>
+ <dl>
+ <dt>
+ <a href="/zh-CN/docs/Creating_a_Python_XPCOM_component" title="en/Creating_a_Python_XPCOM_component">创建 Python XPCOM 组件</a></dt>
+ <dd>
+ 如何使用Python创建简单的<a href="/en/XPCOM" title="/en/XPCOM">XPCOM</a>组件的例子。</dd>
+ </dl>
+ <dl>
+ <dt>
+ <a class="external" href="http://www-128.ibm.com/developerworks/webservices/library/co-pyxp1/">PyXPCOM 入门</a></dt>
+ <dd>
+ PyXPCOM是XPCOM与Python之间的一种桥接技术。本节带给你的是PyXPCOM入门级的向导。</dd>
+ </dl>
+ <p><span class="comment">NOTE: The links to Part II and III of this series are broken and I cannot find them on the IBM site. Please update this page if/when the links can be found.</span></p>
+ <p><span class="alllinks"><a href="/Special:Tags?tag=PyXPCOM&amp;language=en" title="Special:Tags?tag=PyXPCOM&amp;language=en">View All...</a></span></p>
+ <h4 id="History" name="History">历史</h4>
+ <p>PyXPCOM was initially developed by <a class="external" href="http://www.activestate.com/">ActiveState Tool Corporation</a>, and <a class="external" href="http://aspn.activestate.com/ASPN/Downloads/Komodo/index/PyXPCOM/">came out</a> of their <a class="external" href="http://www.activestate.com/Products/Komodo">Komodo project</a>. Current releases are now <a class="external" href="http://public.activestate.com/pyxpcom/">integrated</a> with the Mozilla build system.</p>
+ <p>Other Resources<br>
+ <a class="external" href="http://pyxpcomext.mozdev.org/" title="http://pyxpcomext.mozdev.org/">PythonExt</a> - extension that provides PyXPCOM<br>
+ <a class="external" href="http://pyxpcomext.mozdev.org/samples.html" title="http://pyxpcomext.mozdev.org/samples.html">Samples</a> - demo applications using PyXPCOM</p>
+ </td>
+ <td>
+ <h4 id="Community" name="Community">交流</h4>
+ <br>
+ <ul>
+ <li><a class="external" href="http://listserv.activestate.com/mailman/listinfo/pyxpcom">Python-XPCOM bindings mailing list (ActiveState)</a></li>
+ <li><a class="link-irc" href="irc://irc.mozilla.org:6667/pyxpcom">#pyxpcom on irc.mozilla.org</a></li>
+ </ul>
+ <h4 id="Source_Code" name="Source_Code">源代码</h4>
+ <ul>
+ <li>The PyXPCOM code is available here: <a class="external" href="http://hg.mozilla.org/pyxpcom/">http://hg.mozilla.org/pyxpcom/</a></li>
+ <li>To build PyXPCOM, see <a href="/en/Building_PyXPCOM" title="en/Building_PyXPCOM">Building PyXPCOM</a>.</li>
+ </ul>
+ <h4 id="Related_Topics" name="Related_Topics">相关主题</h4>
+ <dl>
+ <dd>
+ <a href="/en/XPCOM" title="en/XPCOM">XPCOM</a></dd>
+ <dd>
+ <a href="/en/PyDOM" title="en/PyDOM">PyDOM</a>: replace JavaScript with Python</dd>
+ <dd>
+ <a class="external" href="http://code.google.com/p/python-spidermonkey/">Python-SpiderMonkey</a></dd>
+ </dl>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<p> </p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/language_bindings/xpconnect/index.html b/files/zh-cn/mozilla/tech/xpcom/language_bindings/xpconnect/index.html
new file mode 100644
index 0000000000..df0270b533
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/language_bindings/xpconnect/index.html
@@ -0,0 +1,67 @@
+---
+title: XPConnect
+slug: Mozilla/Tech/XPCOM/Language_bindings/XPConnect
+translation_of: Mozilla/Tech/XPCOM/Language_bindings/XPConnect
+---
+<p>XPConnect是<a href="/zh-CN/docs/Web/JavaScript">JavaScript</a>和<a href="/zh-CN/docs/Mozilla/Tech/XPCOM">XPCOM</a>之间的桥梁。利用XPConnect,你可以通过JavaScript代码使用XPCOM组件,同时让XPCOM组件与JavaScript对象交互。XPConnect是<a href="/zh-CN/Firefox">Firefox</a>的组成部分,同时也应用于<a href="/zh-CN/docs/Mozilla/Tech/XUL">XUL</a>应用。</p>
+
+<table class="topicpage-table">
+ <tbody>
+ <tr>
+ <td>
+ <h2 id="Documentation" name="Documentation">文档</h2>
+
+ <dl>
+ <dt><a href="/zh-CN/docs/XPConnect/Architecture_basics">结构基础</a></dt>
+ <dd>XPConnect, JavaScript, XPCOM, XUL...</dd>
+ <dt><a href="/zh-CN/docs/XPConnect/Using_components">使用组件</a></dt>
+ <dd>如何与XPCOM组件通信。</dd>
+ <dt><a class="external" href="https://www-archive.mozilla.org/scriptable/faq.html">XPConnect 和 XPIDL 的常见问题解答</a></dt>
+ <dd>关于使用XPConnect和XPIDL的常见问题解答。<strong>该页面尚未迁移至MDN。</strong></dd>
+ <dt><a href="/zh-CN/docs/Mozilla/XPConnect/XPConnect_wrappers">XPConnect Wrappers</a></dt>
+ <dd>XPConnect的wrappers的生成和使用</dd>
+ </dl>
+
+ <p><strong><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Language_bindings/XPConnect/XPConnect_security_membranes">XPConnect 脚本安全</a></strong></p>
+ </td>
+ <td>
+ <h2 id="Tools" name="Tools">工具</h2>
+
+ <ul>
+ <li><a href="/zh-CN/docs/XPConnect/xpcshell">xpcshell</a></li>
+ </ul>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<div class="blockIndicator communitybox" dir="ltr">
+<div class="column-container">
+<h2 id="加入XPCOM社区">加入XPCOM社区</h2>
+
+<div class="column-half">
+<div class="communitysubhead">选择你喜欢的方式来加入讨论:</div>
+
+<ul class="communitymailinglist">
+ <li><a href="https://lists.mozilla.org/listinfo/dev-tech-xpcom">Mailing list</a></li>
+ <li><a href="http://groups.google.com/group/mozilla.dev.tech.xpcom">Newsgroup</a></li>
+ <li><a href="http://groups.google.com/group/mozilla.dev.tech.xpcom/feeds">RSS feed</a></li>
+</ul>
+</div>
+
+<div class="column-half">
+<ul class="communitycontact">
+ <li><strong>IRC: </strong><a href="irc://irc.mozilla.org/developers">#developers</a> <span class="smaller">(<a href="https://wiki.mozilla.org/IRC">learn more</a>)</span></li>
+ <li><strong>Tools: </strong><a href="http://ted.mielczarek.org/code/mozilla/jscomponentwiz/">JavaScript Component Wizard</a>, <a href="http://www.mytools360.com-a.googlepages.com/home#XPComPro">Visual C++ Component Wizard</a>, <a href="http://www.yutools.com/wp/tools/yuxpcomwizard/?lang=en">Visual C++ Component Wizard for Visual Studio 2010</a></li>
+</ul>
+</div>
+</div>
+</div>
+
+<section id="Quick_Links">
+<ol>
+ <li><a href="/en-US/docs/Mozilla/XPCOM">XPCOM</a></li>
+ <li><a href="/en-US/docs/Mozilla/XPIDL" title="XPIDL is an Interface Description Language used to specify XPCOM interface classes.">XPIDL</a></li>
+ <li><a href="/en-US/docs/Mozilla/Projects/SpiderMonkey" title="Standalone source code releases can be found on the Releases page.">SpiderMonkey</a></li>
+</ol>
+</section>
diff --git a/files/zh-cn/mozilla/tech/xpcom/observer_notifications/index.html b/files/zh-cn/mozilla/tech/xpcom/observer_notifications/index.html
new file mode 100644
index 0000000000..86fdd81a37
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/observer_notifications/index.html
@@ -0,0 +1,880 @@
+---
+title: Observer Notifications
+slug: Mozilla/Tech/XPCOM/Observer_Notifications
+translation_of: Mozilla/Tech/XPCOM/Observer_Notifications
+---
+<h2 id="Observer_topics" name="Observer_topics">Observer topics</h2>
+
+<p>The following are topics that you can observe during the course of an application. Unless otherwise noted you register for the topics using the <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIObserverService" title="">nsIObserverService</a></code>.</p>
+
+<h3 id="Application_startup" name="Application_startup">Application startup</h3>
+
+<p>These are the topics that you can observe on startup, in order of appearance.</p>
+
+<p>If your component requires access to the user profile, or any services which require access to the profile (preferences, bookmarks, and so on) then a common pattern is to register with the <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsICategoryManager" title="">nsICategoryManager</a></code> for the app-startup topic which can be done in the component's registration code, and then in that notification register with the observer service for the profile-after-change notification. See <a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Guide/Receiving_startup_notifications" title="zh-CN/XPCOM/Receiving startup notifications">Receiving startup notifications</a> for more information about how this works.</p>
+
+<p>Starting in Firefox 3.5 components can simply register for the profile-after-change notification in <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsICategoryManager" title="">nsICategoryManager</a></code>.</p>
+
+<table class="standard-table" style="width: 846px;">
+ <tbody>
+ <tr>
+ <th>Topic</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>*</td>
+ <td>
+ <p>Everything.  [<a class="external" href="http://mxr.mozilla.org/mozilla-central/source/xpcom/ds/nsObserverService.cpp#152" title="http://mxr.mozilla.org/mozilla-central/source/xpcom/ds/nsObserverService.cpp#184">nsObserverService.cpp</a>]</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<table class="standard-table" style="height: 880px; width: 846px;">
+ <tbody>
+ <tr>
+ <th>Topic</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>xpcom-startup</td>
+ <td>
+ <p></p><div class="blockIndicator note"><strong>Note:</strong> An extension can no longer be registered to receive this notification in Firefox 4 and later. See <a href="zh-CN/XPCOM/XPCOM_changes_in_Gecko_2.0#Category_registration">XPCOM changes in Gecko 2.0</a> for details.</div><p></p>
+
+ <p>Called when xpcom is initialized. Many things are not available for use at this point. To receive this notification you have to register with <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsICategoryManager" title="">nsICategoryManager</a></code>. The registered component is always retrieved as a singleton (That is getService() will be used to instantiate it).</p>
+ </td>
+ </tr>
+ <tr>
+ <td>app-startup</td>
+ <td>
+ <p></p><div class="blockIndicator note"><strong>Note:</strong> An extension can no longer be registered to receive this notification in Firefox 4 and later. See <a href="zh-CN/XPCOM/XPCOM_changes_in_Gecko_2.0#Category_registration">XPCOM changes in Gecko 2.0</a> for details.</div><p></p>
+
+ <p>General event for application startup. To receive this notification you have to register with <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsICategoryManager" title="">nsICategoryManager</a></code>. Prepend "service," to the contract ID in the category registration to be invoked via getService() instead of createInstance().</p>
+ </td>
+ </tr>
+ <tr>
+ <td>profile-do-change</td>
+ <td>This is fired after the profile has been selected. You will not be able to access user preferences, bookmarks, or anything that uses the profile folder until this event occurs. This occurs after any profile migration.</td>
+ </tr>
+ <tr>
+ <td>profile-after-change</td>
+ <td>
+ <p>This is fired after all the observers for profile-do-change have been notified.</p>
+
+ <p>You can register with <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsICategoryManager" title="">nsICategoryManager</a></code> to receive this notification. Prior to Firefox 3.5, this was available to observers observing the app-startup/xpcom-startup notification.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>final-ui-startup</td>
+ <td>
+ <p>Triggered just before the first window for the application is displayed.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>sessionstore-windows-restored </td>
+ <td>
+ <p>Sent by the session restore process to indicate that all initial browser windows have opened. Note that while the window are open and the chrome loaded the tabs in the windows may still be being restored after this notification.</p>
+
+ <p></p><div class="blockIndicator note"><strong>Note:</strong> This notification is specific to Firefox and SeaMonkey 2.0 applications</div><p></p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Application_shutdown" name="Application_shutdown">Application shutdown</h3>
+
+<p>These are the topics that you can observe on shutdown, in order of appearance.</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th>Topic</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>quit-application-requested</td>
+ <td>Something has requested that the application be shutdown. You can cancel the shutdown from here by setting <code>aSubject.data</code> to <code>true</code> (<code>aSubject</code> is the first parameter to your observer, the data value is an <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupportsPRBool" title="">nsISupportsPRBool</a></code>).</td>
+ </tr>
+ <tr>
+ <td>quit-application-granted</td>
+ <td>All observers have agreed to the shutdown.</td>
+ </tr>
+ <tr>
+ <td>quit-application</td>
+ <td>The application is about to quit. This can be in response to a normal shutdown, or a restart. <div class="blockIndicator note"><strong>Note:</strong> The data value for this notification is either 'shutdown' or 'restart'.</div></td>
+ </tr>
+ <tr>
+ <td>profile-change-net-teardown</td>
+ <td>The network connection is going offline at this point. <div class="blockIndicator note"><strong>Note:</strong> The data value for this notification is either 'shutdown-persist' or 'shutdown-cleanse'.</div></td>
+ </tr>
+ <tr>
+ <td>profile-change-teardown</td>
+ <td>Part of the shutdown, profile data is still available at this point. <div class="blockIndicator note"><strong>Note:</strong> The data value for this notification is either 'shutdown-persist' or 'shutdown-cleanse'.</div></td>
+ </tr>
+ <tr>
+ <td>profile-before-change</td>
+ <td>Called just before the profile is lost. <div class="blockIndicator note"><strong>Note:</strong> The data value for this notification is either 'shutdown-persist' or 'shutdown-cleanse'.</div></td>
+ </tr>
+ <tr>
+ <td>xpcom-will-shutdown </td>
+ <td>Called just before xpcom-shutdown. Observer must not spin event loop.</td>
+ </tr>
+ <tr>
+ <td>xpcom-shutdown</td>
+ <td>This is the end. Many things will not be available here.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Browser" name="Browser">Browser</h3>
+
+<p>These topics indicate interesting things that happen that the browser alerts you to.</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th>Topic</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>browser:purge-session-history</td>
+ <td>Sent when the sanitizer runs to purge all history and other information.</td>
+ </tr>
+ <tr>
+ <td>browser:purge-domain-data</td>
+ <td>Sent after domain-specific history and other information have been purged. The data value is a string form of the domain. </td>
+ </tr>
+ <tr>
+ <td>browser-lastwindow-close-requested</td>
+ <td>Sent when the browser wishes to close the last open browser window. When this is sent, it is possible that other windows may still be open, such as the download manager or preferences. The data value is an <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupportsPRBool" title="">nsISupportsPRBool</a></code>. Recipients may set this to <code>true</code> to abort the close. </td>
+ </tr>
+ <tr>
+ <td>browser-lastwindow-close-granted</td>
+ <td>Sent when all interested parties have responded to the browser-lastwindow-close-requested notification and none of them requested that the close be aborted. After this is sent and handled, the browser window will close. </td>
+ </tr>
+ <tr>
+ <td>browser-delayed-startup-finished</td>
+ <td>Sent when the browser window and all its components have been loaded and initialized.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Documents" name="Documents">Documents</h3>
+
+<p>These topics indicate notifications you can monitor related to DOM documents.</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th>Topic</th>
+ <th>Subject</th>
+ <th>Data</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>chrome-document-global-created </td>
+ <td><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMWindow" title="">nsIDOMWindow</a></code></td>
+ <td>null</td>
+ <td>Sent immediately after a chrome document window has been set up, but before any script code has been executed. This lets extensions inject API into chrome windows as needed (see <a href="/zh-CN/XPCOM_Interface_Reference/nsIDOMGlobalPropertyInitializer" title="zh-CN/XPCOM_Interface_Reference/nsIDOMGlobalPropertyInitializer">nsIDOMGlobalPropertyInitializer</a> for an alternative method of doing this, which uses significantly less memory).<br>
+ <code>data</code> is intentionally left blank.</td>
+ </tr>
+ <tr>
+ <td>content-document-global-created </td>
+ <td><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMWindow" title="">nsIDOMWindow</a></code></td>
+ <td>origin</td>
+ <td>Sent immediately after a web content document window has been set up, but before any script code has been executed. This lets extensions inject API into content windows as needed (see <a href="/zh-CN/XPCOM_Interface_Reference/nsIDOMGlobalPropertyInitializer" title="zh-CN/XPCOM_Interface_Reference/nsIDOMGlobalPropertyInitializer">nsIDOMGlobalPropertyInitializer</a> for an alternative method of doing this).<br>
+ <code>data</code> is a string form of the origin (for use in security checks), eg "http://developer.mozilla.org".</td>
+ </tr>
+ <tr>
+ <td>document-element-inserted </td>
+ <td><a href="/zh-CN/docs/Web/API/Document" title="Document接口表示任何在浏览器中已经加载好的网页,并作为一个入口去操作网页内容(也就是DOM tree)。DOM tree包括像 &lt;body> 、&lt;table>这样的还有其他的元素。它提供了全局操作document的功能,像获取网页的URL和在document里创建一个新的元素。"><code>Document</code></a></td>
+ <td>null</td>
+ <td>Sent immediately after the root element of a document has been created, but before executing any script on it.</td>
+ </tr>
+ <tr>
+ <td>user-interaction-active </td>
+ <td><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMWindow" title="">nsIDOMWindow</a></code></td>
+ <td>null</td>
+ <td>
+ <p>Sent once every 5000ms while this chrome document sees some kind of user activity (for example, keyboard or mouse events), <em>and</em> at the exact moment of the state transition from idle to active.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>user-interaction-inactive </td>
+ <td><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMWindow" title="">nsIDOMWindow</a></code></td>
+ <td>null</td>
+ <td>
+ <p>Sent when the chrome document has seen no user activity for a while. The notification is not repeated during a continuous inactivity period.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Windows" name="Windows">Windows</h3>
+
+<p>These topics indicate points of interest during the lifetime of a window.</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th>Topic</th>
+ <th>Data</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>dom-window-destroyed </td>
+ <td> </td>
+ <td>Called just before a DOM window is destroyed.</td>
+ </tr>
+ <tr>
+ <td>inner-window-destroyed </td>
+ <td> <code>null</code></td>
+ <td>Called when an inner window is removed from the backward/forward cache. See <a href="/zh-CN/Working_with_BFCache" title="zh-CN/Working with BFCache">Working With BFCache</a> for information about the bfcache, and <a href="/zh-CN/Inner_and_outer_windows" title="zh-CN/Inner and outer windows">Inner and outer windows</a> for details about how the window hierarchy works. Extensions that cache information about windows may wish to observe this so they can release information when the window is destroyed.  The <a class="link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=534149" title="https://bugzilla.mozilla.org/show_bug.cgi?id=534149">window id</a> can be obtained from subject.QueryInterface(Components.interfaces.nsISupportsPRUint64).data</td>
+ </tr>
+ <tr>
+ <td>outer-window-destroyed </td>
+ <td><code>null</code></td>
+ <td>Called when an outer window is disconnected from its docshell.  See <a href="/zh-CN/Inner_and_outer_windows" title="zh-CN/Inner and outer windows">Inner and outer windows</a> for details about how the window hierarchy works. Extensions that cache information about windows may wish to observe this so they can release information when the window is destroyed.  The<a class="link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=534149" title="https://bugzilla.mozilla.org/show_bug.cgi?id=534149"> window id</a> can be obtained from subject.QueryInterface(Components.interfaces.nsISupportsPRUint64).data</td>
+ </tr>
+ <tr>
+ <td>toplevel-window-ready</td>
+ <td> </td>
+ <td>Called just after a new top level window has been opened and is ready, but has not yet loaded a document.</td>
+ </tr>
+ <tr>
+ <td>xul-window-destroyed</td>
+ <td> </td>
+ <td>Called just before a XUL window is destroyed.</td>
+ </tr>
+ <tr>
+ <td>xul-window-registered</td>
+ <td> </td>
+ <td>Called just after a top level XUL window is registered with the window mediator service.</td>
+ </tr>
+ <tr>
+ <td>xul-window-visible</td>
+ <td> </td>
+ <td>Called just after a XUL window is made visible.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Spelling checker" name="Spelling checker">Spelling checker </h3>
+
+<p>These topics indicate activities that have occurred related to the spelling checker.</p>
+
+<table class="standard-table" style="width: auto;">
+ <tbody>
+ <tr>
+ <td class="header">Topic</td>
+ <td class="header">Data</td>
+ <td class="header">Description</td>
+ </tr>
+ <tr>
+ <td>spellcheck-dictionary-update</td>
+ <td> </td>
+ <td>Sent by a spell checker implemented by the <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/mozISpellingChecker" title="">mozISpellingChecker</a></code> interface when something has happened that causes a change that may interest the editor; these are received primarily by <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIEditor" title="">nsIEditor</a></code>.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="IO_Notifications" name="IO_Notifications">IO Notifications</h3>
+
+<p>These topics can be used to watch the IO service for useful information.</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th>Topic</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>offline-requested</td>
+ <td>Called to query whether the application can go offline. The attempt to go offline can be canceled.
+ <p></p><div class="blockIndicator note"><strong>Note:</strong> If your code chooses to cancel the attempt to go offline, it <strong>must</strong> notify the user.</div><p></p>
+ </td>
+ </tr>
+ <tr>
+ <td>network:offline-about-to-go-offline</td>
+ <td>Called just before all network IO is taken offline.</td>
+ </tr>
+ <tr>
+ <td>network:offline-status-changed</td>
+ <td>Called when the offline state has changed. <div class="blockIndicator note"><strong>Note:</strong> The data value for this notification 'offline' or 'online' to indicate the new state.</div></td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="HTTP_requests" name="HTTP_requests">HTTP requests</h3>
+
+<p>These are the topics that you can observe during a HTTP request (see <a href="/zh-CN/Setting_HTTP_request_headers" title="zh-CN/Setting_HTTP_request_headers">Setting HTTP request headers</a> and <a href="/zh-CN/Creating_Sandboxed_HTTP_Connections#HTTP_notifications" title="zh-CN/Creating_Sandboxed_HTTP_Connections#HTTP_notifications"> Creating Sandboxed HTTP Connections</a>). Both are passed an <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIHttpChannel" title="">nsIHttpChannel</a></code> as the subject parameter.</p>
+
+<table class="standard-table" style="height: 221px; width: 1106px;">
+ <tbody>
+ <tr>
+ <th>Topic</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>http-on-modify-request</td>
+ <td>Called as a http request is made. The channel is available to allow you to modify headers and such. See <a class="internal" href="/zh-CN/Code_snippets/Tabbed_browser#Getting_the_tab_that_fires_the_http-on-modify-request_notification" title="zh-CN/Code snippets/Tabbed browser#Getting the tab that fires the http-on-modify-request notification">this code snippet</a> to learn how to get the tab that issued the request.</td>
+ </tr>
+ <tr>
+ <td>http-on-opening-request </td>
+ <td>Similar to http-on-modify-request, but called earlier (synchronously during the channel's asyncOpen() call), and some channel atttributes (proxyInfo) may be missing.  Use only if your observer must be called before asyncOpen returns.</td>
+ </tr>
+ <tr>
+ <td>http-on-examine-response</td>
+ <td>Called after a response has been received from the web server. Headers are available on the channel. The response can be accessed and modified via <a href="XPCOM_Interface_Reference/NsITraceableChannel" rel="internal" title="nsITraceableChannel">nsITraceableChannel</a>.</td>
+ </tr>
+ <tr>
+ <td>http-on-examine-cached-response </td>
+ <td>Called instead of http-on-examine-response when a response will be read completely from the cache. Headers are available on the channel.</td>
+ </tr>
+ <tr>
+ <td>http-on-examine-merged-response</td>
+ <td>Called instead of http-on-examine-response when a response will be read partially from cache, and partially from the network (HTTP 206 or 304 response). Headers are available on the channel.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Cookies" name="Cookies">Cookies</h3>
+
+<p>These topics indicate whenever a cookie has been changed (added, changed, cleared, or deleted) or its setting rejected by the browser. See <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsICookieService" title="">nsICookieService</a></code> for details.</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th>Topic</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>cookie-changed</td>
+ <td>Called upon a cookie change (added, changed, cleared, or deleted)</td>
+ </tr>
+ <tr>
+ <td>cookie-rejected</td>
+ <td>Called when the setting of a cookie was rejected by the browser (per the user's preferences)</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Download_Manager" name="Download_Manager">Download Manager</h3>
+
+<p>These topics indicate that events related to the Download Manager have occurred.</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th>Topic</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>download-manager-ui-done</td>
+ <td>Called when the list of downloads in the Download Manager windows finishes updating.  This can happen multiple times, such as when the window first opens, when multiple items are removed, and when entering private browsing mode.</td>
+ </tr>
+ <tr>
+ <td>download-manager-remove-download </td>
+ <td>Called when a download of the list is removed or all the list is cleared. The subject will be the download id wrapped in <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupportsPRUint32" title="">nsISupportsPRUint32</a></code>, for one download removed, or null for multi download remove, for example when the download list is cleared.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Extension_Manager" name="Extension_Manager">Extension Manager</h3>
+
+<div class="note">
+<p><strong>Note:</strong> These notifications are no longer available starting with <span title="(Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1)">Gecko 2.0</span>, instead use <code><a href="/zh-CN/Addons/Add-on_Manager/AddonManager#addAddonListener()" title="https://developer.mozilla.org/zh-CN/Addons/Add-on_Manager/AddonManager#addAddonListener()">AddonManager.addAddonListener()</a></code> to receive similar events.</p>
+</div>
+
+<p>This topic indicates when the extension manager performs some action. Note that any action will be taken the next time the application starts. See <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIExtensionManager" title="">nsIExtensionManager</a></code> for details.</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th>Topic</th>
+ <th>Data</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>em-action-requested</td>
+ <td>item-installed</td>
+ <td>A new extension has been installed.</td>
+ </tr>
+ <tr>
+ <td>em-action-requested</td>
+ <td>item-upgraded</td>
+ <td>A different version of an existing extension has been installed.</td>
+ </tr>
+ <tr>
+ <td>em-action-requested</td>
+ <td>item-uninstalled</td>
+ <td>An addon has been marked to be uninstalled.</td>
+ </tr>
+ <tr>
+ <td>em-action-requested</td>
+ <td>item-enabled</td>
+ <td>An addon has been enabled.</td>
+ </tr>
+ <tr>
+ <td>em-action-requested</td>
+ <td>item-disabled</td>
+ <td>An addon has been disabled.</td>
+ </tr>
+ <tr>
+ <td>em-action-requested</td>
+ <td>item-cancel-action</td>
+ <td>A previous action has been cancelled.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Idle_Service" name="Idle_Service">Idle Service</h3>
+
+<p>This topic indicates when actions related to the Idle Service, provided by the <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIIdleService" title="">nsIIdleService</a></code> interface. Unlike the user-interaction-active and user-interaction-inactive topics listed above, the Idle Service monitors user activity in general, whether related to the Mozilla application or not (acting somewhat like the user activity/inactivity events a screen saver would be interested in).</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th>Topic</th>
+ <th>Data</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>idle</td>
+ <td>The length of time the user has been idle, in milliseconds.</td>
+ <td>Sent when the user becomes idle.</td>
+ </tr>
+ <tr>
+ <td>idle-daily</td>
+ <td>The length of time the user has been idle, in milliseconds.</td>
+ <td>Sent once a day while the user is idle. </td>
+ </tr>
+ <tr>
+ <td>back</td>
+ <td>The length of time the user has been idle, in milliseconds.</td>
+ <td>Sent when the user returns from being idle.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Computer_sleep_and_wake" name="Computer_sleep_and_wake">Computer sleep and wake</h3>
+
+<p>This topic indicates when actions related to the computer going to sleep or waking up occur.  (Note: these notifications are not currently available on Linux.  <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=758848" title="https://bugzilla.mozilla.org/show_bug.cgi?id=758848">See bug 758848</a>.)</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th>Topic</th>
+ <th>Data</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>sleep_notification</td>
+ <td>null</td>
+ <td>Sent when the computer is going to sleep.</td>
+ </tr>
+ <tr>
+ <td>wake_notification</td>
+ <td>null</td>
+ <td>Sent when the computer is waking up.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Login_Manage" name="Login_Manage">Login Manager</h3>
+
+<p>This topic indicates when actions related to the Login Manager occur.</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th>Topic</th>
+ <th>Data</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>passwordmgr-found-form</td>
+ <td>noAutofillForms</td>
+ <td>A login is available for this form, but autofill of forms is disabled, so the form was not automatically filled out.  </td>
+ </tr>
+ <tr>
+ <td>passwordmgr-found-form</td>
+ <td>autocompleteOff</td>
+ <td>A login is available for this form, but autocomplete is disabled.</td>
+ </tr>
+ <tr>
+ <td>passwordmgr-storage-changed</td>
+ <td>addLogin</td>
+ <td>A login has been added to the Login Manager's database. The notification's subject is the login that was added to the database. </td>
+ </tr>
+ <tr>
+ <td>passwordmgr-storage-changed</td>
+ <td>removeLogin</td>
+ <td>A login was removed from the Login Manager's database. The notification's subject is the login that was removed from the database. </td>
+ </tr>
+ <tr>
+ <td>passwordmgr-storage-changed</td>
+ <td>modifyLogin</td>
+ <td>A login in the Login Manager's database was modified. The notification's subject is an array whose first entry is the old login and whose second entry is the new one. </td>
+ </tr>
+ <tr>
+ <td>passwordmgr-storage-changed</td>
+ <td>removeAllLogins</td>
+ <td>All logins have been removed from the Login Manager's database. </td>
+ </tr>
+ <tr>
+ <td>passwordmgr-storage-changed</td>
+ <td>hostSavingEnabled</td>
+ <td>Host saving has been enabled. </td>
+ </tr>
+ <tr>
+ <td>passwordmgr-storage-changed</td>
+ <td>hostSavingDisabled</td>
+ <td>Host saving has been disabled. </td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Places" name="Places">Places</h3>
+
+<p>This topic indicates when actions related to Places (the history and bookmarks database) occur.</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th>Topic</th>
+ <th>Data</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>places-autocomplete-feedback-updated</td>
+ <td> </td>
+ <td>Sent when Places updates the location bar's autocompletion display.</td>
+ </tr>
+ <tr>
+ <td>places-connection-closed</td>
+ <td> </td>
+ <td>Sent after Places has closed its database connection. Once this has been sent, no Places features will work. </td>
+ </tr>
+ <tr>
+ <td>places-connection-closing</td>
+ <td> </td>
+ <td>
+ <p>Sent as the last notification before the Places service closes its database connection. </p>
+
+ <div class="warning"><strong>Warning:</strong> This is for internal use only.</div>
+ </td>
+ </tr>
+ <tr>
+ <td>places-database-locked</td>
+ <td> </td>
+ <td>The Places database is currently locked by a third-party process and cannot be opened.</td>
+ </tr>
+ <tr>
+ <td>places-favicons-expired</td>
+ <td> </td>
+ <td>Sent when all favicons have been expired. </td>
+ </tr>
+ <tr>
+ <td>places-init-complete</td>
+ <td> </td>
+ <td>The Places database has been successfully initialized. You should wait until this notification occurs before querying the places database.</td>
+ </tr>
+ <tr>
+ <td>places-maintenance-finished</td>
+ <td> </td>
+ <td>Sent when maintenance of the Places database is complete; this is done periodically in the background to keep the Places database tidy.</td>
+ </tr>
+ <tr>
+ <td>places-shutdown</td>
+ <td> </td>
+ <td>Sent when Places shuts down. If you are referencing instances of <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/mozIStorageStatement" title="">mozIStorageStatement</a></code> referencing Places databases when this notification occurs, you should call their <code><a href="https://developer.mozilla.org/zh-CN/docs/XPCOM_Interface_Reference/mozIStorageStatement#finalize()">mozIStorageStatement.finalize()</a></code> method </td>
+ </tr>
+ <tr>
+ <td>places-sync-finished</td>
+ <td> </td>
+ <td>Sent when the Places database has been successfully flushed to disk.</td>
+ </tr>
+ <tr>
+ <td>places-will-close-connection</td>
+ <td> </td>
+ <td>
+ <p>Sent when the Places service is about to close its database connection. Only necessary cleanup tasks should run at this point, and nothing should be added to the database. In addition, after this has been sent, no Places APIs should be called. </p>
+
+ <div class="warning"><strong>Warning:</strong> This is for internal use only.</div>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Session_Store" name="Session_Store">Session Store</h3>
+
+<p>These topics are used when actions related to Session Store occur.</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th>Topic</th>
+ <th>Data</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>sessionstore-state-read</td>
+ <td> </td>
+ <td>Sent immediately after session store data is read and before it's used. </td>
+ </tr>
+ <tr>
+ <td>sessionstore-state-finalized</td>
+ <td> </td>
+ <td>Sent immediately after the session is restored.</td>
+ </tr>
+ <tr>
+ <td>sessionstore-state-write</td>
+ <td> </td>
+ <td>Sent immediately before the session store data is written to disk. </td>
+ </tr>
+ <tr>
+ <td>sessionstore-state-write-complete</td>
+ <td> </td>
+ <td>Sent immediately after the session store data is written to disk.</td>
+ </tr>
+ <tr>
+ <td>sessionstore-state-purge-complete</td>
+ <td> </td>
+ <td> </td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Private_browsing" name="Private_browsing">Private browsing</h3>
+
+<p>These topics indicate when actions related to private browsing occur.</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th>Topic</th>
+ <th>Data</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>private-browsing</td>
+ <td>enter</td>
+ <td>Sent when private browsing mode is activated. </td>
+ </tr>
+ <tr>
+ <td>private-browsing</td>
+ <td>exit</td>
+ <td>Sent when private browsing mode is deactivated. </td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Bookmarks" name="Bookmarks">Bookmarks</h3>
+
+<p>These topics indicate when actions related to bookmarks occur.</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th>Topic</th>
+ <th>Data</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>bookmarks-restore-begin</td>
+ <td>json</td>
+ <td>Sent just before bookmarks are restored from JSON. </td>
+ </tr>
+ <tr>
+ <td>bookmarks-restore-begin</td>
+ <td>html</td>
+ <td>Sent just before bookmarks are restored from HTML. If bookmarks will be restored into a specific folder, observers will be passed an <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupportsPRInt64" title="">nsISupportsPRInt64</a></code> through their subject parameters indicating the ID of the folder. The subject is null otherwise. </td>
+ </tr>
+ <tr>
+ <td>bookmarks-restore-begin</td>
+ <td>html-initial</td>
+ <td>Sent just before bookmarks are restored from HTML on initial import. If bookmarks are restored into a specific folder, observers will be passed an <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupportsPRInt64" title="">nsISupportsPRInt64</a></code> through their subject parameters indicating the ID of the folder. The subject is null otherwise. </td>
+ </tr>
+ <tr>
+ <td>bookmarks-restore-success</td>
+ <td>json</td>
+ <td>Sent just after bookmarks are restored from JSON. </td>
+ </tr>
+ <tr>
+ <td>bookmarks-restore-success</td>
+ <td>html</td>
+ <td>Sent just after bookmarks are restored from HTML. If bookmarks were restored into a specific folder, observers will be passed an <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupportsPRInt64" title="">nsISupportsPRInt64</a></code> through their subject parameters indicating the ID of the folder. The subject is null otherwise. </td>
+ </tr>
+ <tr>
+ <td>bookmarks-restore-success</td>
+ <td>html-initial</td>
+ <td>Sent just after bookmarks are restored from HTML on initial import. If bookmarks were restored into a specific folder, observers will be passed an <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupportsPRInt64" title="">nsISupportsPRInt64</a></code> through their subject parameters indicating the ID of the folder. The subject is null otherwise. </td>
+ </tr>
+ <tr>
+ <td>bookmarks-restore-failed</td>
+ <td>json</td>
+ <td>Sent when bookmarks could not be sucessfully restored from JSON. </td>
+ </tr>
+ <tr>
+ <td>bookmarks-restore-failed</td>
+ <td>html</td>
+ <td>Sent when bookmarks could not be successfully restored from HTML. If bookmarks were to have been restored into a specific folder, observers will be passed an <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupportsPRInt64" title="">nsISupportsPRInt64</a></code> through their subject parameters indicating the ID of the folder. The subject is null otherwise. </td>
+ </tr>
+ <tr>
+ <td>bookmarks-restore-failed</td>
+ <td>html-initial</td>
+ <td>Sent when bookmarks could not be successfully restored from HTML on intial import. If bookmarks were to have been restored into a specific folder, observers will be passed an <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupportsPRInt64" title="">nsISupportsPRInt64</a></code> through their subject parameters indicating the ID of the folder. The subject is null otherwise. </td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Themes" name="Themes">Themes</h3>
+
+<p>These topics indicate when actions related to themes occur.</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th>Topic</th>
+ <th>Data</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>lightweight-theme-preview-requested </td>
+ <td>json</td>
+ <td>Sent when the user requests to preview a lightweight theme, but before existing windows are styled with the new theme.</td>
+ </tr>
+ <tr>
+ <td>lightweight-theme-change-requested </td>
+ <td>json</td>
+ <td>Sent to indicate that the user has chosen a new theme in the add-ons manager, but before the change takes effect.</td>
+ </tr>
+ <tr>
+ <td>lightweight-theme-changed </td>
+ <td>-</td>
+ <td>Sent after the current theme is changed.</td>
+ </tr>
+ <tr>
+ <td>lightweight-theme-styling-update </td>
+ <td>json</td>
+ <td>Sent when the current theme being used is changed; this is sent even when the user is previewing a theme, not just when the theme is actually selected.</td>
+ </tr>
+ <tr>
+ <td>lightweight-theme-list-changed </td>
+ <td>-</td>
+ <td>The list of available lightweight themes has changed.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Developer_tools">Developer tools</h3>
+
+<p>These topics let you know about things that have happened related to Firefox's built-in developer tools.</p>
+
+<p> </p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <th>Topic</th>
+ <th>Data</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>highlighter-ready </td>
+ <td>-</td>
+ <td>
+ <p>Sent when the highlighter component is initialized.</p>
+
+ <div class="note"><strong>Note:</strong> This is used by the Inspector to detect when it should begin its initialization process.</div>
+ </td>
+ </tr>
+ <tr>
+ <td>inspector-closed </td>
+ <td>-</td>
+ <td>Sent when the Inspector tool is closed.</td>
+ </tr>
+ <tr>
+ <td>inspector-editor-closed </td>
+ <td>-</td>
+ <td>Sent after the attribute-value editor has been closed.</td>
+ </tr>
+ <tr>
+ <td>inspector-editor-opened </td>
+ <td>-</td>
+ <td>Sent after the attribute-value editor has been opened and initialized.</td>
+ </tr>
+ <tr>
+ <td>inspector-editor-saved </td>
+ <td>-</td>
+ <td>Sent when changes have been saved in the attribute-value editor.</td>
+ </tr>
+ <tr>
+ <td>inspector-highlighting </td>
+ <td>-</td>
+ <td>Sent every time a different node in the page gets highlighted.</td>
+ </tr>
+ <tr>
+ <td>inspector-opened </td>
+ <td>-</td>
+ <td>Sent after the Inspector tool has finished its initialization.</td>
+ </tr>
+ <tr>
+ <td>inspector-ruleview-ready </td>
+ <td>-</td>
+ <td>Sent when the inspector's CSS Rule View is opened and initialized.</td>
+ </tr>
+ <tr>
+ <td>inspector-state-restored </td>
+ <td>-</td>
+ <td>Sent when the Inspector is re-opened after a tab switch.</td>
+ </tr>
+ <tr>
+ <td>inspector-treepanel-ready </td>
+ <td>-</td>
+ <td>Sent when the Inspector's Tree Panel is opened and initialized.</td>
+ </tr>
+ <tr>
+ <td>inspector-unhighlighting </td>
+ <td>-</td>
+ <td>Sent every time the highlighter stops highlighting a node.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Telemetry">Telemetry</h3>
+
+<table class="standard-table" style="width: auto;">
+ <tbody>
+ <tr>
+ <td class="header">Topic</td>
+ <td class="header">Data</td>
+ <td class="header">Description</td>
+ </tr>
+ <tr>
+ <td>gather-telemetry </td>
+ <td>-</td>
+ <td>Sent by the telemetry service when it's time to start gathering telemetry data, since the telemetry ping is coming soon.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Plugins">Plugins</h3>
+
+<table class="standard-table" style="width: auto;">
+ <tbody>
+ <tr>
+ <td class="header">Topic</td>
+ <td class="header">Data</td>
+ <td class="header">Description</td>
+ </tr>
+ <tr>
+ <td>plugin-crashed</td>
+ <td>-</td>
+ <td>Sent when a plugin has crashed.</td>
+ </tr>
+ </tbody>
+</table>
+
+<p> </p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/index.html
new file mode 100644
index 0000000000..92f0a47369
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/index.html
@@ -0,0 +1,16 @@
+---
+title: XPCOM glue classes
+slug: Mozilla/Tech/XPCOM/Reference/Glue_classes
+tags:
+ - Classes
+ - Landing
+ - NeedsTranslation
+ - TopicStub
+ - XPCOM
+translation_of: Mozilla/Tech/XPCOM/Reference/Glue_classes
+---
+<p><span class="seoSummary">These "glue" classes are provided to make it easier to use XPCOM from C++ code.</span> When these classes are used by a component, you may need to link the component against the XPCOM glue library.</p>
+<p></p><div class="row topicpage-table">
+ <div class="section"><dl><dl><dt></dt></dl></dl></div>
+ <div class="section"><dl><dt class="landingPageList"><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Glue_classes/nsCOMPtr">使用nsCOMPtr</a></dt><dd class="landingPageList">这篇文档是对nsCOMPtr的一个总述。如果您所遇到的问题,无法在该文档中找到答案,可能就没有其他文档可以回答它了。您需要求助于XPCOM新闻组或者有nsCOMPtr使用经验的人来求解,或者根据自己的试验获取答案。</dd></dl></div>
+ </div><p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/nscomptr/getting_started_guide/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/nscomptr/getting_started_guide/index.html
new file mode 100644
index 0000000000..32dedcf102
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/nscomptr/getting_started_guide/index.html
@@ -0,0 +1,478 @@
+---
+title: 入门指南
+slug: Mozilla/Tech/XPCOM/Reference/Glue_classes/nsCOMPtr/Getting_Started_Guide
+translation_of: Mozilla/Tech/XPCOM/Using_nsCOMPtr/Getting_Started_Guide
+---
+<p>下面开始探讨智能指针问题。</p>
+<h3 id="Introduction" name="Introduction">介绍</h3>
+<h4 id="What_is_nsCOMPtr.3F" name="What_is_nsCOMPtr.3F">什么是 <code>nsCOMPtr</code>?</h4>
+<p><code>nsCOMPtr</code> 是防止内存泄漏的一种工具。</p>
+<p><code>nsCOMPtr</code> 是一种智能指针。 它是一个模板类,在使用上类似C/C++中的普通指针。如:可使用*或者-&gt;得到其所指定的内容。<code>nsCOMPtr</code>之所以智能,是因为它不像一般指向XPCOM对象的指针<code>,nsCOMPtr还管理</code><code>AddRef</code>, <code>Release</code>, 和<code>QueryInterface</code>方法。 <code>nsCOMPtr</code>是在以下源文件中定义的:</p>
+<ul>
+ <li>{{ Source("xpcom/glue/nsCOMPtr.h", "xpcom/glue/nsCOMPtr.h") }}</li>
+ <li>{{ Source("xpcom/glue/nsCOMPtr.cpp", "xpcom/glue/nsCOMPtr.cpp") }}</li>
+</ul>
+<p>...though you probably don't want to look in there, just yet.</p>
+<p><code>利用nsCOMPtr</code>,比使用原始的XPCOM接口指针,能够把代码写的更简短,更清晰,更明白,更安全。</p>
+<h4 id=".5BXP.5DCOM_Basics:_Ownership_and_Reference_Counting" name=".5BXP.5DCOM_Basics:_Ownership_and_Reference_Counting">[XP]COM Basics: Ownership and Reference Counting</h4>
+<p>这段是对XPCOM的一些基本问题的一个复习。对<code>nsCOMPtr</code>s的理解,需要对XPCOM有一个基本的认识。您可通过以下方式对XPCOM进行学习。<a class="external" href="http://www.develop.com/dbox/">Don Box</a>的<a class="external" href="http://www.amazon.com/exec/obidos/ASIN/0201634465">Essential COM</a> 介绍了COM的基本规则和使用。 Don Box 在 <a class="external" href="http://www.amazon.com/exec/obidos/ASIN/0201379686">Effective COM</a>.一书中更详尽的说明了COM的细节,缺陷和易犯的错误。您还需要对C++有基本的了解。这里列举三本比较有用的书:Bjarne Stroustrup 的 <a class="external" href="http://www.amazon.com/exec/obidos/ASIN/0201889544">The C++ Programming Language</a>,Scott Meyers 的 <a class="external" href="http://www.amazon.com/exec/obidos/ASIN/0201924889">Effective C++</a> 和 <a class="external" href="http://www.amazon.com/exec/obidos/ASIN/020163371X">More Effective C++</a>。</p>
+<p>All XPCOM objects are allocated on the heap. Clients don't get to know much about the implementation of any such object. They reference it only through a pointer to an `interface', i.e., the static type of the pointer is a pointer to an abstract base class, the actual object pointed to is a class derived from that abstract base class. The XPCOM object is said to `implement that interface'. The client's reference to the object is typically called `an interface pointer'.</p>
+<p>An object may implement many interfaces. Each interface is (at least conceptually) separately `reference counted'. That is, the interface keeps a count of the number of clients holding references to it. When that count goes to zero, the interface may <code>delete</code> itself. Clients are expected to keep this reference count accurate by incrementing it when they acquire a reference to the interface, and decrementing it before they let go. To facilitate this, all interfaces inherit from an abstract base class that provides the member functions <code>AddRef</code>, and <code>Release</code>.</p>
+<p>A rule of XPCOM is that any function that creates or returns an interface pointer will have already <code>AddRef</code>ed it. The caller can then hold onto the reference indefinitely, calling <code>Release</code> when it no longer needs it. When the last pointer to an interface is <code>Release</code>d, the interface (and consequently, typically the underlying object) will <code>delete</code> itself. As long as there is an outstanding <code>AddRef</code> against the interface, it continues to exist. If you forget to call <code>Release</code>, the object will leak, i.e., the storage for that object will never be reclaimed. Leaks are bad <code><span class="nowiki">:-)</span></code>.</p>
+<p>A reference through which you will call <code>AddRef</code> and <code>Release</code> is called an <strong>owning reference</strong>. It holds a stake in the underlying object. That object cannot go away until the owning reference has relinquished its claim. Not all references need to be owning references. In fact, if two objects somehow end up owning each other (even transitively) it becomes difficult for either of those object to be reclaimed without adding some `out-of-band' mechanism for breaking the ownership cycle. The document <a href="/en/XPCOM_ownership_guidelines" title="en/XPCOM_ownership_guidelines">Some COM Ownership Guidelines</a> provides some hints on when ownership is needed. The following lists are good starting point, but by no means complete.</p>
+<p>You use an owning reference when</p>
+<ul>
+ <li>you created the object;</li>
+ <li>you got the object from a function that <em>might</em> have created it, e.g., any `getter' function, such as <code>QueryInterface</code>, or <code>CreateInstance</code>. All good getters <code>AddRef</code> the interface pointers they produce, thus providing you with an owning reference;</li>
+ <li>you will hold onto the reference longer than the scope of the function in which you acquired it, e.g., you got it as a parameter, but you're hanging onto it in a member variable (see, for example, {{ web.link("#Comparison_1", "Comparison 1") }}, below).</li>
+</ul>
+<p>You don't need an owning reference when</p>
+<ul>
+ <li>the object is passed in as a parameter, and you <em>don't</em> need to keep it any longer than the scope of this function;</li>
+ <li>the object's lifetime is known to contain yours in some well defined way, e.g., in the nodes of a tree, parent nodes keep owning references to their children, children need not keep owning references to their parents.</li>
+</ul>
+<p>It turns out that reference counting by hand is hard for programmers to get right. It may sound simple, but in practice it's very easy to forget to <code>Release</code> at the appropriate moment. Or to <code>AddRef</code> too many or too few times.</p>
+<h4 id="How_does_nsCOMPtr_help.3F" name="How_does_nsCOMPtr_help.3F">How does <code>nsCOMPtr</code> help?</h4>
+<p><code>nsCOMPtr</code> manages <code>AddRef</code>, <code>Release</code>, and other red-tape for you. An <code>nsCOMPtr</code> looks and acts as much like a raw XPCOM interface pointer as C allows, but it knows it owns the object it points to. This takes a little getting used to on your part, but ends up with less typing, clearer, safer code, and less leaks.</p>
+<p>For instance, here is a typical snippet of code (at its most compact) where you assign a XPCOM interface pointer into a member variable, i.e., the body of a `setter' function, side-by-side using raw XPCOM interface pointers and <code>nsCOMPtr</code>s. </p>
+<p>对照1.设置成员变量。</p>
+<p> </p>
+<table>
+ <caption>
+  </caption>
+ <tbody>
+ <tr>
+ <td>
+ <pre class="eval">
+<span class="comment">// raw [XP]COM interface pointers...</span>
+<span class="comment">// given: |nsIFoo* mFooPtr;|</span>
+
+<span class="comment"><span class="nowiki">/*
+ |AddRef| the new value if it's not
+ |NULL|; assign it in; and |Release|
+ the old value, if any (so we don't
+ leak it).
+
+ This order of assignment is special
+ and must be used to avoid particular
+ ownership bugs.
+ */</span></span>
+
+<strong>NS_IF_ADDREF(aFooPtr);
+nsIFoo* temp = mFooPtr;</strong>
+mFooPtr = aFooPtr;
+<strong>NS_IF_RELEASE(temp);</strong>
+</pre>
+ </td>
+ <td>
+ <pre class="eval">
+<span class="comment">// |nsCOMPtr|...</span>
+<span class="comment">// given: |nsCOMPtr&lt;nsIFoo&gt; mFooPtr;|</span>
+
+<span class="comment"><span class="nowiki">/*
+ This assignment automatically
+ |Release|s the old value in
+ |mFooPtr|, if any, and |AddRef|s the
+ new one, in the appropriate sequence
+ to avoid the ownership bug mentioned
+ earlier.
+ */</span></span>
+
+
+
+
+
+mFooPtr = aFooPtr;
+
+</pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<p>Additionally, the class using raw XPCOM interface pointers will need a destructor to <code>Release</code> <code>mFooPtr</code><span class="nowiki">; and a constructor to ensure that </span><code>mFooPtr</code> is initially set to <code>NULL</code> (or some other reasonable value).</p>
+<p><code>nsCOMPtr</code> helps you write code that is leak-proof, exception safe, and significantly less verbose than you would with raw XPCOM interface pointers. With <code>nsCOMPtr</code>, you may never have to call <code>AddRef</code>, <code>Release</code>, or <code>QueryInterface</code> by hand.</p>
+<p>You still have to understand XPCOM. You still have to know which functions return interface pointers that have already been <code>AddRef</code>ed and which don't. You still have to ensure your program logic doesn't produce circularly referencing garbage. <code>nsCOMPtr</code> is not a panacea. It is, however, helpful, easy to use, well-tested, and polite. It doesn't require that a function author cooperate with you, nor does your use force others to use it.</p>
+<h3 id="Using_nsCOMPtr" name="Using_nsCOMPtr"><span style="font-family: monospace;">使用</span><code>nsCOMPtr</code></h3>
+<h4 id="The_Basics" name="The_Basics">The Basics</h4>
+<p>多数情况下,使用nsCOMPtr和一个一般的XPCOM接口指针是类似的。注意在声明中的细微区别。</p>
+<table>
+ <caption>
+ 对照 2. 相似点: <code>nsCOMPtr</code>类似于 XPCOM接口指针</caption>
+ <tbody>
+ <tr>
+ <td>
+ <pre class="eval">
+<span class="comment">// raw [XP]COM interface pointers...</span>
+
+nsIFoo<strong><span class="nowiki">*</span></strong> fooPtr <strong><span class="nowiki">= 0</span></strong><span class="nowiki">;
+ </span><span class="comment">// ...</span>
+fooPtr-&gt;SomeFunction(x, y, z);
+AnotherFunction(fooPtr);
+
+if ( fooPtr )
+ <span class="comment">// ...</span>
+
+if ( fooPtr == foo2Ptr )
+ <span class="comment">// ...</span>
+</pre>
+ </td>
+ <td>
+ <pre class="eval">
+<span class="comment">// |nsCOMPtr|...</span>
+
+<strong>nsCOMPtr&lt;</strong>nsIFoo<strong>&gt;</strong> fooPtr;
+<span class="comment">// ...</span>
+fooPtr-&gt;SomeFunction(x, y, z);
+AnotherFunction(fooPtr);
+
+if ( fooPtr )
+ <span class="comment">// ...</span>
+
+if ( fooPtr == foo2Ptr )
+ <span class="comment">// ...</span>
+</pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<p> </p>
+<p>有两点主要区别。第一:不需要也不再允许调用<code>AddRef</code> 和 <code>Release</code>方法。 </p>
+<table>
+ <caption>
+ 对照 3. 不同点: <code>AddRef</code> <span style="font-family: monospace;">和 </span><code>Release</code> 对于 <code>nsCOMPtr</code>s 来说是非法的。</caption>
+ <tbody>
+ <tr>
+ <td>
+ <pre class="eval">
+<span class="comment">// raw [XP]COM interface pointers...</span>
+<span class="comment">// given: |nsIFoo* mFooPtr;|</span>
+
+ <span class="comment">/*
+ Note: this sequence is not the
+ correct order to do assign
+ raw pointers anyway (see
+ {{ Anch("Comparison 1") }}) but I need it
+ for this comparison.
+ */</span>
+
+NS_IF_RELEASE(mFooPtr);
+
+mFooPtr = aFooPtr;
+NS_IF_ADDREF(mFooPtr);
+
+</pre>
+ </td>
+ <td>
+ <pre class="eval">
+<span class="comment">// |nsCOMPtr|...</span>
+<span class="comment">// given: |nsCOMPtr&lt;nsIFoo&gt; mFooPtr;|</span>
+
+ <span class="comment">/*
+ You no longer need, nor will the
+ compiler let you, call |AddRef|,
+ or |Release|.
+ */</span>
+
+
+
+<span class="warning">NS_IF_RELEASE(mFooPtr);</span>
+ <span class="comment">// Error: |Release| is private</span>
+mFooPtr = aFooPtr;
+<span class="warning">NS_IF_ADDREF(mFooPtr);</span>
+ <span class="comment">// Error: |AddRef| is private</span>
+</pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<p> </p>
+<p>第二:使用 <a href="/en/Using_nsCOMPtr/Reference_Manual#.60Out.27_Parameters:_getter_AddRefs" title="en/Using_nsCOMPtr/Reference_Manual#.60Out.27_Parameters:_getter_AddRefs"><code>getter_AddRefs</code></a> 标识nsCOMPtr,作为获取指针返回值的函数的参数,而不能只使用<code>nsCOMPtr</code>的地址作为参数。</p>
+<table>
+ <caption>
+ 对照 4. 不同点: <span style="font-family: monospace;">当 </span><code>nsCOMPtr</code> 作为输出参数时,使用 getter_AddRefs。</caption>
+ <tbody>
+ <tr>
+ <td>
+ <pre class="eval">
+<span class="comment">// raw [XP]COM interface pointers...</span>
+
+nsIFoo* foo;
+
+GetFoo(<strong>&amp;</strong>foo);
+</pre>
+ </td>
+ <td>
+ <pre class="eval">
+<span class="comment">// |nsCOMPtr|s...</span>
+
+nsCOMPtr&lt;nsIFoo&gt; foo;
+
+GetFoo(<strong>getter_AddRefs(</strong>foo<strong>)</strong>);
+</pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<p> </p>
+<p>以上是对nsCOMPtrS的一些说明,基本涵盖了平日使用的90%。以下是在一些复杂情况下,对其的细节说明。</p>
+<p> </p>
+<h4 id="A_Few_Details" name="A_Few_Details">一些细节</h4>
+<p> </p>
+<p>以下是更多细节让您更了解 <code>nsCOMPtr</code>。</p>
+<p>通常,通过调用 <code>QueryInterface 获取接口指针</code><span style="font-family: monospace;">。</span> <code>QueryInterface</code> 是一个 getter 函数,由以上方法,可通过 <code>getter_AddRefs</code> 方法来获取。</p>
+<table>
+ <caption>
+ The hard way to <code>QueryInterface</code> into an <code>nsCOMPtr</code>.</caption>
+ <tbody>
+ <tr>
+ <td>
+ <pre class="eval">
+<span class="comment">// A way (though not the best way) to |QueryInterface| into an |nsCOMPtr|...</span>
+
+nsCOMPtr&lt;nsIFoo&gt; foo;
+
+nsresult rv = bar-&gt;QueryInterface(NS_GET_IID(nsIFoo), getter_AddRefs(foo));
+
+ <span class="comment">// Or, if you're a savvy [XP]COM programmer,</span>
+ <span class="comment">// you use the type-safe version...</span>
+nsresult rv = CallQueryInterface(bar, getter_AddRefs(foo));
+</pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<p><code>因为 QueryInterface</code> 使用频繁,<code>nsCOMPtr</code> 提供了一种特殊方式对其调用。这种方式是类型安全的,<code>QueryInterface的返回值能</code>直接构造nsCOMPtr。这种构造方式比通过赋值进行构造效率更高。这种方式是 <a href="/en/Using_nsCOMPtr/Reference_Manual#nsCOMPtr.3CT.3E_.3D_do_QueryInterface.28_nsISupports.2A_.29.2CnsCOMPtr.3CT.3E_.3D_do_QueryInterface.28_nsISupports.2A.2C_nsresult.2A_.29" title="en/Using_nsCOMPtr/Reference_Manual#nsCOMPtr.3CT.3E_.3D_do_QueryInterface.28_nsISupports.2A_.29.2CnsCOMPtr.3CT.3E_.3D_do_QueryInterface.28_nsISupports.2A.2C_nsresult.2A_.29"><code>do_QueryInterface</code></a> 。通过使用这种方式,以上例子可写为:</p>
+<table>
+ <caption>
+ How to <code>QueryInterface</code> into an <code>nsCOMPtr</code>.</caption>
+ <tbody>
+ <tr>
+ <td>
+ <pre class="eval">
+<span class="comment">// The best way to |QueryInterface| into an |nsCOMPtr|...</span>
+
+nsresult rv;
+nsCOMPtr&lt;nsIFoo&gt; foo( <strong>do_QueryInterface(</strong>bar, &amp;rv<strong>)</strong> );
+
+ <span class="comment">// Or, if you don't care about the |nsresult|</span>
+nsCOMPtr&lt;nsIFoo&gt; foo( <strong>do_QueryInterface(</strong>bar<strong>)</strong> );
+</pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<p><code>nsCOMPtr</code> happily calls <code>AddRef</code> and <code>Release</code> implicitly. This same favor is <em>not</em> extended to <code>QueryInterface</code>. <code>nsCOMPtr</code> does not <code>QueryInterface</code> on assignment without your explicit permission in the form of the <code>do_QueryInterface</code> directive. You need never worry about hidden queries. However, be aware that if you <em>should</em> have queried but didn't, e.g., when assigning in a raw pointer where C allows the assignment, but XPCOM wouldn't, <code>nsCOMPtr</code> will <a href="/en/Using_nsCOMPtr/Reference_Manual#Type_Safeguards" title="en/Using_nsCOMPtr/Reference_Manual#Type_Safeguards">assert at runtime</a>. Use <code>do_QueryInterface</code> whenever you assign in a pointer to a XPCOM interface of a different type, even if that type happens to derive from the base type of the <code>nsCOMPtr</code></p>
+<p> </p>
+<table>
+ <caption>
+ 对照6. <code>do_QueryInterface</code> 避免了XPCOM 中的类型错误。</caption>
+ <tbody>
+ <tr>
+ <td>
+ <pre class="eval">
+class nsIBar
+  : public nsIFoo ... { ... };
+
+nsIBar* p = ...;
+
+ <span class="comment">// C thinks every |nsIBar*| is an</span>
+ <span class="comment">// |nsIFoo*|, therefore, C allows</span>
+ <span class="comment">// this...</span>
+nsCOMPtr&lt;nsIFoo&gt; <span class="warning">foo = p;</span>
+ <span class="comment">// ...even though it is an [XP]COM</span>
+ <span class="comment">// type error</span>
+</pre>
+ </td>
+ <td>
+ <pre class="eval">
+class nsIBar
+  : public nsIFoo ... { ... };
+
+nsIBar* p = ...;
+
+
+
+ <span class="comment">// No type error here...</span>
+nsCOMPtr&lt;nsIFoo&gt; foo( <strong>do_QueryInterface(</strong>p<strong>)</strong> );
+
+
+</pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<p>Remember, the C type system and the XPCOM type system are really two independent things. Because XPCOM interfaces are expressed as abstract C base classes, you may be tempted to let C handle the differences, or to use C casts to navigate between interface types. This is wrong. The only sanctioned way to get between XPCOM types is with <code>QueryInterface</code>. In the example above, there is no reason to assume that the <code>nsIFoo*</code> C pulls out of <code>p</code> would be the same one that <code>p-&gt;QueryInterface()</code> would return.</p>
+<p><a href="/en/Using_nsCOMPtr/Reference_Manual#nsCOMPtr.3CT.3E_.3D_dont_AddRef.28_T.2A_.29.2CnsCOMPtr.3CT.3E_.3D_getter_AddRefs.28_T.2A_.29" title="en/Using_nsCOMPtr/Reference_Manual#nsCOMPtr.3CT.3E_.3D_dont_AddRef.28_T.2A_.29.2CnsCOMPtr.3CT.3E_.3D_getter_AddRefs.28_T.2A_.29"><code>dont_AddRef</code></a> is a similar directive that helps you when you assign in a pointer that has already been <code>AddRef</code>ed, e.g., because you called a getter that returned the pointer as its function result.</p>
+<table>
+ <caption>
+ Using <code>dont_AddRef</code>.</caption>
+ <tbody>
+ <tr>
+ <td>
+ <pre class="eval">
+nsCOMPtr&lt;nsIFoo&gt; foo( <strong>dont_AddRef(</strong>CreateFoo()<strong>)</strong> );
+ <span class="comment">// |CreateFoo| |AddRef|s its result, as all good getters do</span>
+</pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<h4 id="Something_nsCOMPtr_Doesn.27t_Do" name="Something_nsCOMPtr_Doesn.27t_Do">Something <code>nsCOMPtr</code> <em>Doesn't</em> Do</h4>
+<p>An <code>nsCOMPtr</code> does all that is necessary to behave as an owning reference. A given <code>nsCOMPtr</code> does not, however, cooperate in making <em>other</em> owning pointers. After learning how <code>nsCOMPtr</code> automatically <code>AddRef</code>s a pointer as it is being assigned <em>in</em>, the natural assumption is that it does the same thing when assigning <em>out</em>. Here is a snippet of code that demonstrates this misconception.</p>
+<table>
+ <tbody>
+ <tr>
+ <td>
+ <pre class="eval">
+<span class="comment">// Incorrect assumptions about |nsCOMPtr|...</span>
+
+nsresult
+nsCacheRecord::GetFileSpec( nsIFileSpec** aFileSpecResult )
+ <span class="comment">/*
+ ...fills in the callers |nsFileSpec*| (which the caller supplied
+ the address of) with a copy of my member variable |mFileSpec|,
+ an |nsCOMPtr|. I.e., this function is a `getter'.
+
+ Remember: good [XP]COM getters always |AddRef| their result.
+ */</span>
+ {
+ <span class="comment">// ...</span>
+ *aFileSpec = mFileSpec;
+ <span class="warning"><span class="comment">// the |nsCOMPtr| should take care of the refcount here, right?</span></span>
+ return NS_OK;
+ }
+</pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<p>Plainly, the author believed (though perhaps with some question) that the <code>nsCOMPtr</code>, <code>mFileSpec</code>, would <code>AddRef</code> automatically as it was assigned into <code><span class="nowiki">*aFileSpec</span></code>. This is <em>not</em> the case. An <code>nsCOMPtr</code> automatically calls <code>AddRef</code> and <code>Release</code> (only) on its <em>own</em> behalf. In all other situations, it is designed to be a drop in replacement for a raw XPCOM pointer. Where ever an <code>nsCOMPtr</code> is used in a situation where a raw pointer is needed, the <code>nsCOMPtr</code> automatically provides one.</p>
+<table>
+ <tbody>
+ <tr>
+ <td>
+ <pre class="eval">
+<span class="comment">// |nsCOMPtr| produces a raw pointer when needed...</span>
+
+nsCOMPtr&lt;nsIFoo&gt; foo = ...;
+
+ <span class="comment">// 1. Assigning into a raw pointer</span>
+nsIFoo* raw_foo = foo;
+
+ <span class="comment">// 2. Assigning into another |nsCOMPtr|</span>
+nsCOMPtr&lt;nsIFoo&gt; foo2 = foo;
+
+ <span class="comment">// 3. As a parameter</span>
+SetFoo(foo);
+
+ <span class="comment">// 4. Testing the value in an |if| expression</span>
+ <span class="comment">// 5. Calling a member function</span>
+if ( foo )
+ foo-&gt;DoSomething();
+</pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<p>In all of these cases, pretty much the exact same code is executed (case 2 is slightly different, but the intent is the same). In each case, you are essentially extracting the raw pointer value for your own purpose. If the <code>nsCOMPtr</code> <code>AddRef</code>ed the value each time you did that, cases 4 and 5 would obviously always generate leaks. <code>SetFoo</code>, from case 3, would have to be written two different ways when given an <code>nsCOMPtr</code>, it would know the value was already <code>AddRef</code>ed, and when given a raw pointer it would assume the value was not <code>AddRef</code>ed. Actually the contradictions run deeper than that. All these cases show that automatically <code>AddRef</code>ing on `output' makes <code>nsCOMPtr</code>s and raw-pointers act differently from the point of view of the clients. The goal is to make them act the same so that <code>nsCOMPtr</code>s can be a drop in replacement (modulo managing its own `ownership').</p>
+<p>Given what you now know, the rule is predictable. As described above, and unless you tell it otherwise, an <code>nsCOMPtr</code> <code>AddRef</code>s when you assign <em>in</em> to it. It does nothing when you assign <em>out</em> of it.</p>
+<h4 id="Where_should_I_use_nsCOMPtrs.3F" name="Where_should_I_use_nsCOMPtrs.3F">Where should I use <code>nsCOMPtr</code>s?</h4>
+<p>You should use an <code>nsCOMPtr</code> any place you use an interface pointer as an owning reference, i.e., where you call <code>AddRef</code> and <code>Release</code> on it. You should use <code>nsCOMPtr</code> as a member variable, where it will simplify setters, and eliminate constructors, destructors, and assignment operators. You should use <code>nsCOMPtr</code> on the stack, where it makes calling <code>QueryInterface</code> almost pleasant, and eliminates the complex logic that falls out of error handling.</p>
+<h4 id="Where_shouldn.27t_I_use_nsCOMPtrs.3F" name="Where_shouldn.27t_I_use_nsCOMPtrs.3F">Where shouldn't I use <code>nsCOMPtr</code>s?</h4>
+<p>Don't use <code>nsCOMPtr</code>s where you don't need an owning reference. See <a href="/en/XPCOM_ownership_guidelines" title="en/XPCOM_ownership_guidelines">Some COM Ownership Guidelines</a>. <code>nsCOMPtr</code> is designed to be used with XPCOM interfaces, so don't use it with non-interfaces with specific exceptions described <a href="/en/Using_nsCOMPtr/Getting_Started_Guide#nsCOMPtrs_for_non-interface_classes" title="en/Using_nsCOMPtr/Getting_Started_Guide#nsCOMPtrs_for_non-interface_classes">below</a>. Don't use <code>nsCOMPtr</code>s in XPCOM interfaces. Don't use them in plain old C code; <code>nsCOMPtr</code>s are, of course, a C only construct. <a href="/en/Using_nsCOMPtr/Reference_Manual#Casting" title="en/Using_nsCOMPtr/Reference_Manual#Casting">Never cast</a> an <code>nsCOMPtr</code>, it's almost guaranteed to leak.</p>
+<h4 id="nsCOMPtrs_for_non-interface_classes" name="nsCOMPtrs_for_non-interface_classes"><code>nsCOMPtr</code>s for non-interface classes</h4>
+<p>Appropriately formatted answer to come, in the meanwhile, the full details are available in <a class="link-news" href="news://news.mozilla.org/scc-3E1526.12182423042001@h-204-29-187-152.netscape.com">this news posting</a> (<a class="external" href="http://groups.google.com/group/netscape.public.mozilla.xpcom/browse_frm/thread/77258f1cd7d99773/268b949066f2ba4a?hl=de&amp;q=#268b949066f2ba4a" title="http://groups.google.com/group/netscape.public.mozilla.xpcom/browse_frm/thread/77258f1cd7d99773/268b949066f2ba4a?hl=de&amp;q=#268b949066f2ba4a">via Google Groups</a>).</p>
+<h4 id="nsCOMPtrs_in_function_signatures" name="nsCOMPtrs_in_function_signatures"><code>nsCOMPtr</code>s in function signatures</h4>
+<p>In general, you won't want to use <code>nsCOMPtr</code> in the signature of XPCOM (i.e., `scriptable') functions. <code>nsCOMPtr</code> is not currently directly supported by IDL. However, you may sometime be tempted to use an <code>nsCOMPtr</code> in a non-scriptable function.</p>
+<h5 id="nsCOMPtr.3CT.3E_f.28.29_don.27t_return_an_nsCOMPtr" name="nsCOMPtr.3CT.3E_f.28.29_don.27t_return_an_nsCOMPtr"><span class="warning"><code>nsCOMPtr&lt;T&gt; f()</code></span> 不返回 <code>nsCOMPtr</code></h5>
+<p>This practice is dangerous. Returning an <code>AddRef</code>ed pointer in almost any form as a function result leads to several potential errors, some of which are leaks, some of which are dangling pointers. Returning an <code>nsCOMPtr</code> may seem like a good idea (since it tells clients you are giving them ownership), however it can be the cause of an dangling pointer. Consider:</p>
+<table>
+ <tbody>
+ <tr>
+ <td>
+ <pre class="eval">
+<span class="comment">// Don't return |nsCOMPtr|s...</span>
+nsCOMPtr&lt;nsIFoo&gt; CreateFoo();
+<span class="comment">// ...</span>
+
+<span class="warning">nsIFoo* myFoo = CreateFoo();</span> <span class="comment">// Oops: |myFoo| now dangles!</span>
+ <span class="comment">// |CreateFoo| returns an |nsCOMPtr|, which</span>
+ <span class="comment">// automatically |Release|s right after this</span>
+ <span class="comment">// assignment. Now |myFoo| refers to a</span>
+ <span class="comment">// deleted object.</span>
+</pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<p>You can tell callers you are giving them ownership in a way that doesn't pose this hazard by returning a <code>already_AddRefed&lt;T&gt;</code> (see bug <a class="external" href="http://bugzilla.mozilla.org/show_bug.cgi?id=59212"><span class="nowiki">#59212</span></a>). An <code>nsCOMPtr</code> knows not to <code>AddRef</code> a value that is <code>already_AddRefed</code>.</p>
+<table>
+ <tbody>
+ <tr>
+ <td>
+ <pre class="eval">
+<span class="comment">// Preferred form: if you must return a pointer, use |already_AddRefed|...</span>
+already_AddRefed&lt;nsIFoo&gt; CreateFoo();
+<span class="comment">// ...</span>
+
+nsIFoo* myFoo1 = CreateFoo(); <span class="comment">// doesn't dangle</span>
+nsCOMPtr&lt;nsIFoo&gt; myFoo2( CreateFoo() ); <span class="comment">// doesn't leak</span>
+nsCOMPtr&lt;nsIFoo&gt; myFoo3( dont_AddRef(CreateFoo()) ); <span class="comment">// redundant, but legal and correct</span>
+</pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<p>Compare this to the most frequent leaks caused by returning a raw pointer you have already <code>AddRef</code>ed:</p>
+<table>
+ <tbody>
+ <tr>
+ <td>
+ <pre class="eval">
+<span class="comment">// Don't return raw pointers; that incites leaks...</span>
+nsIFoo* CreateFoo(); <span class="comment">// returns an |AddRef|ed pointer</span>
+<span class="comment">// ...</span>
+
+<span class="warning">nsCOMPtr&lt;nsIFoo&gt; myFoo = CreateFoo();</span> <span class="comment">// Oops: leak;</span>
+nsCOMPtr&lt;nsIFoo&gt; myFoo( <span class="notice">dont_AddRef(</span>CreateFoo()<span class="notice">)</span> );
+ <span class="comment">// Since |CreateFoo| already |AddRef|s its result, we must remind</span>
+ <span class="comment">// our |nsCOMPtr| not to. It's easy to forget. Prevent it in advance</span>
+ <span class="comment">// by not returning pointers as function results, or else by returning</span>
+ <span class="comment">// an |already_AddRefed&lt;T&gt;| as above.</span>
+</pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<h5 id="void_f.28_nsCOMPtr.3CT.3E_.29_don.27t_pass_an_nsCOMPtr_by_value" name="void_f.28_nsCOMPtr.3CT.3E_.29_don.27t_pass_an_nsCOMPtr_by_value"><span class="warning"><code>void f( nsCOMPtr&lt;T&gt; )</code></span> don't pass an <code>nsCOMPtr</code> by value</h5>
+<p>This practice is wasteful, but not otherwise harmful. There is no need to <code>AddRef</code> parameters, as they are guaranteed to live as long as the function call. You only need to <code>AddRef</code> them as you store them in a structure that will live longer than the function call. Which means the appropriate member of that structure should be an <code>nsCOMPtr</code>, not the function parameter. Additionally, this signature may confuse callers into thinking they need an <code>nsCOMPtr</code> just to call the function.</p>
+<h5 id="void_f.28_const_nsCOMPtr.3CT.3E&amp;_.29_don.27t_pass_an_nsCOMPtr_by_const_reference" name="void_f.28_const_nsCOMPtr.3CT.3E&amp;_.29_don.27t_pass_an_nsCOMPtr_by_const_reference"><span class="warning"><code>void f( const nsCOMPtr&lt;T&gt;&amp; )</code></span> don't pass an <code>nsCOMPtr</code> by <code>const</code> reference</h5>
+<p>Exactly as the signature above, this practice is wasteful, but not otherwise harmful, and has the same impact as passing an <code>nsCOMPtr</code> by value if the caller only supplied a raw pointer.</p>
+<h5 id="void_f.28_nsCOMPtr.3CT.3E.2A_.29_avoid_passing_an_nsCOMPtr_by_address.2C_if_possible" name="void_f.28_nsCOMPtr.3CT.3E.2A_.29_avoid_passing_an_nsCOMPtr_by_address.2C_if_possible"><span class="warning"><code>void f( nsCOMPtr&lt;T&gt;* )</code></span> avoid passing an <code>nsCOMPtr</code> by address, if possible</h5>
+<p>This practice requires callers to have an <code>nsCOMPtr</code>, and requires them to do a little extra work, as <code>operator&amp;</code> for <code>nsCOMPtr</code>s is <code>private</code> (to help prevent <a href="/en/Using_nsCOMPtr/Reference_Manual#Casting" title="en/Using_nsCOMPtr/Reference_Manual#Casting">leaks caused by casting</a>; also see {{ Bug(59414) }}). This is an acceptable way to declare `in/out' parameters, but prefer passing <code>nsCOMPtr</code>s by reference, as below.</p>
+<table>
+ <tbody>
+ <tr>
+ <td>
+ <pre class="eval">
+<span class="comment">// Passing an |nsCOMPtr| by pointer requires extra work...</span>
+void f( nsCOMPtr&lt;nsIFoo&gt;* );
+<span class="comment">// ...</span>
+
+nsCOMPtr&lt;nsIFoo&gt; myFoo = ...;
+
+f( <span class="notice">address_of(</span>myFoo<span class="notice">)</span> );
+</pre>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<h5 id="void_f.28_nsCOMPtr.3CT.3E&amp;_.29_do_pass_an_nsCOMPtr_by_reference_for_.60in.2Fout.27_parameters" name="void_f.28_nsCOMPtr.3CT.3E&amp;_.29_do_pass_an_nsCOMPtr_by_reference_for_.60in.2Fout.27_parameters"><code>void f( nsCOMPtr&lt;T&gt;&amp; )</code> do pass an <code>nsCOMPtr</code> by reference for `in/out' parameters</h5>
+<p>This is the prefered scheme for providing `in/out' parameters. If you were to use a raw pointer instead, your function couldn't know what ownership relationship the caller had to the input value, and hence, couldn't know whether to <code>Release</code> it or not before assigning in the new value. By declaring the parameter as an <code>nsCOMPtr&amp;</code>, the relationship is explicit.</p>
+<h3 id="Summary" name="Summary">Summary</h3>
+<p>An <code>nsCOMPtr</code> is an owning reference. Whatever it points to has been <code>AddRef</code>ed, counting the <code>nsCOMPtr</code> as one of its `owners'. An <code>nsCOMPtr</code> always calls <code>Release</code> before letting go, whether the <code>nsCOMPtr</code> is letting go so that it can point to a different object, or because the <code>nsCOMPtr</code> is going out of scope. Any time a new value is assigned into an <code>nsCOMPtr</code>, the <code>nsCOMPtr</code> automatically always <code>Release</code>s its old referent, if any, and (unless you tell it you already have) <code>AddRef</code>s the new.</p>
+<p>You use an <code>nsCOMPtr</code> exactly as you would a raw XPCOM interface pointer in almost all cases. You won't have to explictly call <code>AddRef</code> or <code>Release</code> through it, nor will the compiler allow it. The only place you can't use an <code>nsCOMPtr</code> without change is where a raw XPCOM interface pointer is an `out' parameter. In this case, you wrap the <code>nsCOMPtr</code> with <a href="/en/Using_nsCOMPtr/Reference_Manual#.60Out.27_Parameters:_getter_AddRefs" title="en/Using_nsCOMPtr/Reference_Manual#.60Out.27_Parameters:_getter_AddRefs"><code>getter_AddRefs</code></a> (see {{ web.link("#Comparison_4", "Comparison 4") }}).</p>
+<p>When assigning into an <code>nsCOMPtr</code>, you will usually just supply another pointer (either a raw XPCOM interface pointer or an <code>nsCOMPtr</code>), with no additional directives { web.link("#Comparison_1", "Comparison 1") }}). As stated above, with no directives, the <code>nsCOMPtr</code> will <code>Release</code> its old referent, if any, and <code>AddRef</code> the new. This is appropriate when the thing you're assigning in hasn't yet been <code>AddRef</code>ed to account for the new reference. This is typically the case when you are assigning in a pointer that you <em>didn't</em> call a function to get, e.g., one that was passed in as a parameter, or that you pulled out of a structure.</p>
+<p>You can tell <code>nsCOMPtr</code> it doesn't need to <code>AddRef</code> the new value on assignment by wrapping the new value in <a href="/en/Using_nsCOMPtr/Reference_Manual#nsCOMPtr.3CT.3E_.3D_dont_AddRef.28_T.2A_.29.2CnsCOMPtr.3CT.3E_.3D_getter_AddRefs.28_T.2A_.29" title="en/Using_nsCOMPtr/Reference_Manual#nsCOMPtr.3CT.3E_.3D_dont_AddRef.28_T.2A_.29.2CnsCOMPtr.3CT.3E_.3D_getter_AddRefs.28_T.2A_.29"><code>dont_AddRef</code></a>. Do this, for example, when you got the new value from a function which, like all good XPCOM getters, already called <code>AddRef</code> on your behalf.</p>
+<p>You may not assign in a pointer to a different interface type; you must first query it to the right type (see, e.g., {{ web.link("#Comparison_6", "Comparison 6") }} and the surrounding discussion). <code>nsCOMPtr</code> <em>never</em> calls <code>QueryInterface</code> implicitly, i.e., you must call it yourself, or explictly ask <code>nsCOMPtr</code> to call it with <a href="/en/Using_nsCOMPtr/Reference_Manual#nsCOMPtr.3CT.3E_.3D_do_QueryInterface.28_nsISupports.2A_.29.2CnsCOMPtr.3CT.3E_.3D_do_QueryInterface.28_nsISupports.2A.2C_nsresult.2A_.29" title="en/Using_nsCOMPtr/Reference_Manual#nsCOMPtr.3CT.3E_.3D_do_QueryInterface.28_nsISupports.2A_.29.2CnsCOMPtr.3CT.3E_.3D_do_QueryInterface.28_nsISupports.2A.2C_nsresult.2A_.29"><code>do_QueryInterface</code></a>. The <code>do_QueryInterface</code> directive allows you to do the query as part of the assignment. This better facilitates constructing an <code>nsCOMPtr</code> directly from the right value, rather than constructing it and assigning in the correct value later. Construction alone is more efficient than construction followed by assignment. Prefer construction over assignment whereever reasonable. Be careful not to apply <code>do_QueryInterface</code> to a function returning an <code>AddRef</code>ed pointer [see <a href="/en/Using_nsCOMPtr/Reference_Manual#nsCOMPtr.3CT.3E_.3D_.2F.2A_call_QueryInterface_but_don.27t_AddRef_.2A.2F" title="en/Using_nsCOMPtr/Reference_Manual#nsCOMPtr.3CT.3E_.3D_.2F.2A_call_QueryInterface_but_don.27t_AddRef_.2A.2F">this short section</a> for an explanation]</p>
+<p>For more details, continue on to the <a href="/en/Using_nsCOMPtr/Reference_Manual" title="en/Using_nsCOMPtr/Reference_Manual">Reference Manual</a>.</p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/nscomptr/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/nscomptr/index.html
new file mode 100644
index 0000000000..d9c427784a
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/glue_classes/nscomptr/index.html
@@ -0,0 +1,56 @@
+---
+title: 使用nsCOMPtr
+slug: Mozilla/Tech/XPCOM/Reference/Glue_classes/nsCOMPtr
+translation_of: Mozilla/Tech/XPCOM/Reference/Glue_classes/nsCOMPtr
+---
+<p>这篇文档是对nsCOMPtr的一个总述。如果您所遇到的问题,无法在该文档中找到答案,可能就没有其他文档可以回答它了。您需要求助于XPCOM新闻组或者有nsCOMPtr使用经验的人来求解,或者根据自己的试验获取答案。</p>
+
+<p>如果您尚未使用过nsCOMPtr,您正好可从这里开始。当您使用了一段时间后,或者遇到了不熟悉的领域,或者出现编译错误,您可返回该文档,在参考手册或者FAQ中求助。</p>
+
+<h2 id="Contents" name="Contents">内容</h2>
+
+<ol>
+ <li><a href="/en/Using_nsCOMPtr/Status,_Recent_Changes,_and_Plans" title="en/Using_nsCOMPtr/Status,_Recent_Changes,_and_Plans">状态,最新修改和计划</a>
+
+ <ol>
+ <li><a href="/en/Using_nsCOMPtr/Status,_Recent_Changes,_and_Plans#Recent_changes_to_nsCOMPtr" title="en/Using_nsCOMPtr/Status,_Recent_Changes,_and_Plans#Recent_changes_to_nsCOMPtr"><span style="font-family: monospace;">对</span><code>nsCOMPtr的最新修改</code></a></li>
+ </ol>
+ </li>
+ <li><a href="/en/Using_nsCOMPtr/Getting_Started_Guide" title="en/Using_nsCOMPtr/Getting_Started_Guide">入门指南</a>
+ <ol>
+ <li><a href="/en/Using_nsCOMPtr/Getting_Started_Guide#Introduction" title="en/Using_nsCOMPtr/Getting_Started_Guide#Introduction">介绍</a></li>
+ <li><a href="/en/Using_nsCOMPtr/Getting_Started_Guide#Using_nsCOMPtr" title="en/Using_nsCOMPtr/Getting_Started_Guide#Using_nsCOMPtr">使用 <code>nsCOMPtr</code></a></li>
+ <li><a href="/en/Using_nsCOMPtr/Getting_Started_Guide#Summary" title="en/Using_nsCOMPtr/Getting_Started_Guide#Summary">小结</a></li>
+ </ol>
+ </li>
+ <li><a href="/en/Using_nsCOMPtr/Reference_Manual" title="en/Using_nsCOMPtr/Reference_Manual">参考手册</a>
+ <ol>
+ <li><a href="/en/Using_nsCOMPtr/Reference_Manual#The_Basics" title="en/Using_nsCOMPtr/Reference_Manual#The_Basics">基本原理</a></li>
+ <li><a href="/en/Using_nsCOMPtr/Reference_Manual#Initialization_and_Assignment" title="en/Using_nsCOMPtr/Reference_Manual#Initialization_and_Assignment">初始化和赋值</a></li>
+ <li><a href="/en/Using_nsCOMPtr/Reference_Manual#Using_an_nsCOMPtr.3CT.3E_as_a_T.2A" title="en/Using_nsCOMPtr/Reference_Manual#Using_an_nsCOMPtr.3CT.3E_as_a_T.2A">Using an <code>nsCOMPtr&lt;T&gt;</code> as a <code>T*</code></a></li>
+ <li><a href="/en/Using_nsCOMPtr/Reference_Manual#Efficiency_and_Correctness" title="en/Using_nsCOMPtr/Reference_Manual#Efficiency_and_Correctness">Efficiency and Correctness</a></li>
+ <li><a href="/en/Using_nsCOMPtr/Reference_Manual#Compiler_Annoyances" title="en/Using_nsCOMPtr/Reference_Manual#Compiler_Annoyances">Compiler Annoyances</a></li>
+ </ol>
+ </li>
+ <li><a href="/en/Using_nsCOMPtr/Frequently_Asked_Questions" title="en/Using_nsCOMPtr/Frequently_Asked_Questions">FAQ</a>
+ <ol>
+ <li><a href="/en/Using_nsCOMPtr/Frequently_Asked_Questions#Buildtime_Errors" title="en/Using_nsCOMPtr/Frequently_Asked_Questions#Buildtime_Errors">编译时错误</a></li>
+ <li><a href="/en/Using_nsCOMPtr/Frequently_Asked_Questions#Runtime_Errors" title="en/Using_nsCOMPtr/Frequently_Asked_Questions#Runtime_Errors">运行时错误</a></li>
+ <li><a href="/en/Using_nsCOMPtr/Frequently_Asked_Questions#How_do_I..." title="en/Using_nsCOMPtr/Frequently_Asked_Questions#How_do_I...">How do I...</a></li>
+ <li><a href="/en/Using_nsCOMPtr/Frequently_Asked_Questions#General" title="en/Using_nsCOMPtr/Frequently_Asked_Questions#General">General</a></li>
+ <li><a href="/en/Using_nsCOMPtr/Frequently_Asked_Questions#Bibliography" title="en/Using_nsCOMPtr/Frequently_Asked_Questions#Bibliography">Bibliography</a></li>
+ </ol>
+ </li>
+</ol>
+
+<div class="originaldocinfo">
+<h2 id="Original_Document_Information" name="Original_Document_Information">Original Document Information</h2>
+
+<ul>
+ <li>Author(s): <a class="link-mailto" href="mailto:scc@mozilla.org">Scott Collins</a></li>
+ <li>Last Updated Date: December 11, 2001</li>
+ <li>Copyright Information: Copyright © 1999, 2000 by the Mozilla organization; use is subject to the <a class="external" href="http://www.mozilla.org/MPL/">MPL</a>. Portions of this content are © 1998–2007 by individual mozilla.org contributors; content available under a Creative Commons license | <a class="external" href="http://www.mozilla.org/foundation/licensing/website-content.html">Details</a>.</li>
+</ul>
+</div>
+
+<p> </p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/index.html
new file mode 100644
index 0000000000..188a822ae6
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/index.html
@@ -0,0 +1,14 @@
+---
+title: XPCOM reference
+slug: Mozilla/Tech/XPCOM/Reference
+translation_of: Mozilla/Tech/XPCOM/Reference
+---
+<p>This reference describes the interfaces and functions provided by the <a href="/en-US/docs/Mozilla/Tech/XPCOM">XPCOM</a> library. In addition, it details the various helper classes and functions, as well as the components, provided by the <a href="/en-US/docs/Mozilla/Tech/XPCOM/Glue">XPCOM glue</a> library. The contents herein are oriented primarily toward extension developers and people embedding XPCOM in other projects.</p>
+<div class="note">
+ <p><strong>Note:</strong> If you're working on a module in the Mozilla codebase that's compiled with the <code>MOZILLA_INTERNAL_API</code> flag set, some of these APIs -- the string functions and classes in particular -- are not the ones you should be using. See the <a href="/en-US/docs/Mozilla/Tech/XPCOM/Guide/Internal_strings">XPCOM internal string guide</a> for documentation of the internal string API used within the Mozilla codebase.</p>
+</div>
+<p></p><div class="row topicpage-table">
+ <div class="section"><dl><dl><dt class="landingPageList"><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Glue_classes">XPCOM glue classes</a></dt><dd class="landingPageList">These "glue" classes are provided to make it easier to use XPCOM from C++ code.</dd><dt class="landingPageList"><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface">XPCOM Interface Reference</a></dt><dd class="landingPageList"><span class="long_text short_text" id="result_box" lang="zh-CN"><span>这是一个</span><span>由</span><span>Mozilla平台</span><span>提供</span><span>的</span><span>XPCOM接口</span><span>的</span><span>参考</span></span>.</dd></dl></dl></div>
+ <div class="section"><dl><dt></dt></dl></div>
+ </div><p></p>
+<p>Many XPCOM pages return an <code><a href="/en-US/docs/Mozilla/Tech/XPCOM/Reference/Core_functions/nsresult">nsresult</a></code>. Prior to Gecko 19 (Firefox 19 / Thunderbird 19 / SeaMonkey 2.16), this was an integer that simply returned an error code. It is now a strongly typed <code>enum</code> when XPCOM is built using a C++11 compiler. This causes compile-time errors to occur when improper values are returned as nsresult values, thereby making it easier to catch many bugs.</p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/index.html
new file mode 100644
index 0000000000..da50238f6f
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/interface/index.html
@@ -0,0 +1,11 @@
+---
+title: XPCOM Interface Reference
+slug: Mozilla/Tech/XPCOM/Reference/Interface
+translation_of: Mozilla/Tech/XPCOM/Reference/Interface
+---
+<p><span class="long_text short_text" id="result_box" lang="zh-CN"><span>这是一个</span><span>由</span><span>Mozilla平台</span><span>提供</span><span>的</span><span>XPCOM接口</span><span>的</span><span>参考</span></span>.</p>
+<div style=""><ul><li><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIAccessibleProvider">nsIAccessibleProvider</a></li><li><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIClipboard">nsIClipboard</a></li><li><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIClipboardHelper">nsIClipboardHelper</a></li><li><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIConsoleService">nsIConsoleService</a></li><li><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMClientRect">nsIDOMClientRect</a></li><li><a href="/zh-CN/docs/nsIDOMParser">nsIDOMParser</a></li><li><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDirectoryServiceProvider">nsIDirectoryServiceProvider</a></li><li><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFile">nsIFile</a></li><li><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFilePicker">nsIFilePicker</a></li><li><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIHttpChannel">nsIHttpChannel</a></li><li><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIIdleService">nsIIdleService</a></li><li><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsILocalFile">nsILocalFile</a></li><li><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIProcess">nsIProcess</a></li><li><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIPrompt">nsIPrompt</a></li><li><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIPromptService">nsIPromptService</a></li><li><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIScriptableUnicodeConverter">nsIScriptableUnicodeConverter</a></li><li><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISyncMessageSender">nsISyncMessageSender</a></li><li><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsITimer">nsITimer</a></li><li><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/NsITraceableChannel">nsITraceableChannel</a></li><li><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIURI">nsIURI</a></li><li><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIXMLHttpRequest">nsIXMLHttpRequest</a></li></ul></div>
+<h2 id="See_also" name="See_also">相关链接</h2>
+<ul> <li><a href="/zh-cn/XPCOM_Interface_Reference_group" title="https://developer.mozilla.org/zh-cn/XPCOM_Interface_Reference_group">Interfaces grouped by function</a></li>
+</ul>
+<p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiaccessibleprovider/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiaccessibleprovider/index.html
new file mode 100644
index 0000000000..488e504556
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiaccessibleprovider/index.html
@@ -0,0 +1,45 @@
+---
+title: nsIAccessibleProvider
+slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIAccessibleProvider
+tags:
+ - Accessibility
+ - Interfaces
+translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIAccessibleProvider
+---
+<p> </p>
+<p><br>
+ </p><div style="border: solid #ddd 2px; margin-bottom: 12px;">
+<div style="background: #eee; padding: 2px;"><code><a href="https://dxr.mozilla.org/mozilla-central/source/accessible/public/nsIAccessibleProvider.idl" rel="custom">accessible/public/nsIAccessibleProvider.idl</a></code><span style="text-align: right; float: right;"><a href="/zh-CN/docs/Interfaces/About_Scriptable_Interfaces" style="color: #00cc00; font-weight: 700;">脚本化</a></span></div>
+<span style="padding: 4px 2px;">
+
+<i>Please add a summary to this article.</i>
+</span>
+
+<div style="background: #eee; padding: 2px;">
+<span> </span>
+<span style="text-align: right; float: right;">最后修改于Gecko 1.9 (Firefox 3)</span></div>
+</div><p></p>
+<p>Inherits from: <a href="cn/NsISupports">nsISupports</a></p>
+<h2 id="Attributes" name="Attributes">Attributes</h2>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">Attribute</td>
+ <td class="header">Type</td>
+ <td class="header">Description</td>
+ </tr>
+ <tr>
+ <td><code>accessible</code></td>
+ <td><code><a href="cn/NsIAccessible">nsIAccessible</a></code></td>
+ <td>Returns an accessible.
+ <i>
+ Read only</i>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<h3 id="See_also" name="See_also">See also</h3>
+<ul>
+ <li><a href="cn/Accessibility">Accessibility</a></li>
+ <li><a href="cn/NsIAccessible">nsIAccessible</a></li>
+</ul>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiclipboard/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiclipboard/index.html
new file mode 100644
index 0000000000..a1778f2cbb
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiclipboard/index.html
@@ -0,0 +1,91 @@
+---
+title: nsIClipboard
+slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIClipboard
+translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIClipboard
+---
+<p></p><div style="border: solid #ddd 2px; margin-bottom: 12px;">
+<div style="background: #eee; padding: 2px;"><code><a href="https://dxr.mozilla.org/mozilla-central/source/widget/public/nsIClipboard.idl" rel="custom">widget/public/nsIClipboard.idl</a></code><span style="text-align: right; float: right;"><a href="/zh-CN/docs/Interfaces/About_Scriptable_Interfaces" style="color: #00cc00; font-weight: 700;">脚本化</a></span></div>
+<span style="padding: 4px 2px;">
+
+This interface supports basic clipboard operations such as: setting, retrieving, emptying, matching and supporting clipboard data.
+</span>
+
+<div style="background: #eee; padding: 2px;">
+继承于: <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupports" title="">nsISupports</a></code>
+<span style="text-align: right; float: right;">最后修改于Gecko 1.8 (Firefox 1.5 / Thunderbird 1.5 / SeaMonkey 1.0)</span></div>
+</div><p></p>
+<h2 id="Method_overview" name="Method_overview"><span class="long_text short_text" id="result_box" lang="zh-CN"><span>方法</span><span>概述</span></span></h2>
+<table class="standard-table"> <tbody> <tr> <td><code>void <a href="#emptyClipboard()">emptyClipboard</a>(in long aWhichClipboard);</code></td> </tr> <tr> <td><code>void <a href="#forceDataToClipboard()">forceDataToClipboard</a>(in long aWhichClipboard);</code> <span class="inlineIndicator obsolete obsoleteInline" title="(Firefox 1.5 / Thunderbird 1.5 / SeaMonkey 1.0)">已废弃 Gecko 1.8</span></td> </tr> <tr> <td><code>void <a href="#getData()">getData</a>(in nsITransferable aTransferable, in long aWhichClipboard);</code></td> </tr> <tr> <td><code>boolean <a href="#hasDataMatchingFlavors()">hasDataMatchingFlavors</a>([array, size_is(aLength)] in string aFlavorList, in unsigned long aLength, in long aWhichClipboard);</code></td> </tr> <tr> <td><code>void <a href="#setData()">setData</a>(in nsITransferable aTransferable, in nsIClipboardOwner anOwner, in long aWhichClipboard);</code></td> </tr> <tr> <td><code>boolean <a href="#supportsSelectionClipboard()">supportsSelectionClipboard</a>();</code></td> </tr> </tbody>
+</table>
+<h2 id="Constants" name="Constants">常量</h2>
+<p>Most users will expect clipboard operations to use the global clipboard. In fact, the <code>kSelectionClipboard</code> is peculiar to the X Windows System, and not used much even under X.</p>
+<table class="standard-table"> <tbody> <tr> <td class="header">常量名称</td> <td class="header">值</td> <td class="header">描述</td> </tr> <tr> <td><code>kSelectionClipboard</code></td> <td><code>0</code></td> <td>Clipboard for selection.</td> </tr> <tr> <td><code>kGlobalClipboard</code></td> <td><code>1</code></td> <td>Clipboard for global use.</td> </tr> </tbody>
+</table>
+<h2 id="Methods" name="Methods">方法</h2>
+<h3 id="emptyClipboard()" name="emptyClipboard()">emptyClipboard()</h3>
+<p>This method empties the clipboard and notifies the clipboard owner. It empties the "logical" clipboard. It does not clear the native clipboard.</p>
+<pre class="eval">void emptyClipboard(
+ in long aWhichClipboard
+);
+</pre>
+<h6 id="Parameters" name="Parameters">参数</h6>
+<dl> <dt><code>aWhichClipboard</code></dt> <dd>Specifies the clipboard to which this operation applies.</dd>
+</dl>
+<p></p><div class="headingWithIndicator">
+ <h3 id="forceDataToClipboard()">forceDataToClipboard()</h3>
+ <span class="indicatorInHeadline obsolete obsoleteMethod">已废弃 Gecko 1.8 (Firefox 1.5 / Thunderbird 1.5 / SeaMonkey 1.0)</span>
+ </div><p></p>
+<p>Some platforms support deferred notification for putting data on the clipboard This method forces the data onto the clipboard in its various formats This may be used if the application going away.</p>
+<pre class="eval">void forceDataToClipboard(
+ in long aWhichClipboard
+);
+</pre>
+<h6 id="Parameters" name="Parameters">参数</h6>
+<dl> <dt><code>aWhichClipboard</code></dt> <dd>Specifies the clipboard to which this operation applies.</dd>
+</dl>
+<h3 id="getData()" name="getData()">getData()</h3>
+<p>This method retrieves data from the clipboard into a transferable.</p>
+<pre class="eval">void getData(
+ in nsITransferable aTransferable,
+ in long aWhichClipboard
+);
+</pre>
+<h6 id="Parameters" name="Parameters">参数</h6>
+<dl> <dt><code>aTransferable</code></dt> <dd>The transferable to receive data from the clipboard.</dd> <dt><code>aWhichClipboard</code></dt> <dd>Specifies the clipboard to which this operation applies.</dd>
+</dl>
+<h3 id="hasDataMatchingFlavors()" name="hasDataMatchingFlavors()">hasDataMatchingFlavors()</h3>
+<p>This method provides a way to give correct UI feedback about, for instance, whether a paste should be allowed. It does <strong>not</strong> actually retrieve the data and should be a very inexpensive call. All it does is check if there is data on the clipboard matching any of the flavors in the given list.</p>
+<pre class="eval">boolean hasDataMatchingFlavors(
+ [array, size_is(aLength)] in string aFlavorList,
+ in unsigned long aLength,
+ in long aWhichClipboard
+);
+</pre>
+<h6 id="Parameters" name="Parameters">参数</h6>
+<dl> <dt><code>aFlavorList</code></dt> <dd>An array of ASCII strings.</dd> <dt><code>aLength</code></dt> <dd>The length of the <code>aFlavorList</code>.</dd> <dt><code>aWhichClipboard</code></dt> <dd>Specifies the clipboard to which this operation applies.</dd>
+</dl>
+<h6 id="Return_value" name="Return_value">返回值</h6>
+<p>Returns <code>true</code>, if data is present and it matches the specified flavor. Otherwise it returns <code>false</code>.</p>
+<h3 id="setData()" name="setData()">setData()</h3>
+<p>This method sets the data from a transferable on the native clipboard.</p>
+<pre class="eval">void setData(
+ in nsITransferable aTransferable,
+ in nsIClipboardOwner anOwner,
+ in long aWhichClipboard
+);
+</pre>
+<h6 id="Parameters" name="Parameters">参数</h6>
+<dl> <dt><code>aTransferable</code></dt> <dd>The transferable containing the data to put on the clipboard.</dd> <dt><code>anOwner</code></dt> <dd>The owner of the transferable.</dd> <dt><code>aWhichClipboard</code></dt> <dd>Specifies the clipboard to which this operation applies.</dd>
+</dl>
+<h3 id="supportsSelectionClipboard()" name="supportsSelectionClipboard()">supportsSelectionClipboard()</h3>
+<p>This method allows clients to determine if the implementation supports the concept of a separate clipboard for selection.</p>
+<pre class="eval">boolean supportsSelectionClipboard();
+</pre>
+<h6 id="Parameters" name="Parameters">参数</h6>
+<p>None.</p>
+<h6 id="Return_value" name="Return_value">返回值</h6>
+<p>Returns <code>true</code> if <code>kSelectionClipboard</code> is available. Otherwise it returns <code>false</code>.</p>
+<h2 id="See_also" name="See_also">相关链接</h2>
+<ul> <li><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIClipboardOwner" title="">nsIClipboardOwner</a></code></li> <li><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsITransferable" title="">nsITransferable</a></code></li> <li><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIArray" title="">nsIArray</a></code></li> <li><a class="internal" href="/zh-cn/Using_the_Clipboard" title="Using the Clipboard">Using the Clipboard</a></li>
+</ul>
+<p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiclipboardhelper/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiclipboardhelper/index.html
new file mode 100644
index 0000000000..b4c7881597
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiclipboardhelper/index.html
@@ -0,0 +1,65 @@
+---
+title: nsIClipboardHelper
+slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIClipboardHelper
+translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIClipboardHelper
+---
+<div style="border: solid #ddd 2px; margin-bottom: 12px;">
+<div style="background: #eee; padding: 2px;"><code><a href="https://dxr.mozilla.org/mozilla-central/source/widget/public/nsIClipboardHelper.idl" rel="custom">widget/public/nsIClipboardHelper.idl</a></code><span style="text-align: right; float: right;"><a href="/zh-CN/docs/Interfaces/About_Scriptable_Interfaces" style="color: #00cc00; font-weight: 700;">脚本化</a></span></div>
+<span style="padding: 4px 2px;">
+
+<code>nsIClipboardHelper接口是能够快速方便的使用</code> nsIClipboard 接口中常用方法的辅助接口.
+</span>
+
+<div style="background: #eee; padding: 2px;">
+继承于: <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupports" title="">nsISupports</a></code>
+<span style="text-align: right; float: right;">最后修改于Gecko 1.7 </span></div>
+</div>
+<h2 id="Method_overview" name="Method_overview">方法概述</h2>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>void <a href="#copyString()">copyString</a>(in AString aString);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#copyStringToClipboard()">copyStringToClipboard</a>(in AString aString, in long aClipboardID);</code></td>
+ </tr>
+ </tbody>
+</table>
+<h2 id="Methods" name="Methods">方法</h2>
+<h3 id="copyString()" name="copyString()">copyString()</h3>
+<p>该方法将字符串复制到默认剪切板.</p>
+<pre class="eval">void copyString(
+ in AString aString
+);
+</pre>
+<h6 id="Parameters" name="Parameters">参数</h6>
+<dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ 将要复制到剪切板的字符串.</dd>
+</dl>
+<h3 id="copyStringToClipboard()" name="copyStringToClipboard()">copyStringToClipboard()</h3>
+<p>该方法将字符串复制到指定剪切板.</p>
+<pre class="eval">void copyStringToClipboard(
+ in AString aString,
+ in long aClipboardID
+);
+</pre>
+<h6 id="Parameters" name="Parameters">参数</h6>
+<dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ 将要复制到指定剪切板的字符串.</dd>
+ <dt>
+ <code>aClipboardID</code></dt>
+ <dd>
+ 指定剪切板的ID(例如<code>kSelectionClipboard</code>).</dd>
+</dl>
+<h2 id="See_also" name="See_also">相关连接</h2>
+<ul>
+ <li><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIClipboard" title="">nsIClipboard</a></code></li>
+ <li><a href="/zh-cn/Using_the_Clipboard" title="zh-cn/Using the Clipboard">Using the Clipboard</a></li>
+</ul>
+<p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiconsoleservice/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiconsoleservice/index.html
new file mode 100644
index 0000000000..b373505057
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiconsoleservice/index.html
@@ -0,0 +1,215 @@
+---
+title: nsIConsoleService
+slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIConsoleService
+translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIConsoleService
+---
+<div class="warning">
+ <p>Error Console在Firefox中已经过期,只有将<code>devtools.errorconsole.enabled<font face="Open Sans, sans-serif"><span style="line-height: 23.33333396911621px;">
+ <i>
+ 设为</i>
+ </span></font></code><code>true<em>才能使用</em></code>. 对于web应用使用 <a href="/en-US/docs/Tools/Web_Console" title="/en-US/docs/Tools/Web_Console">Web Console </a>代替, 对于浏览器中的chrome应用,使用 <a href="/en-US/docs/Tools/Browser_Console" title="/en-US/docs/Tools/Browser_Console">Browser Console</a> 代替 .</p>
+</div>
+<p></p><div style="border: solid #ddd 2px; margin-bottom: 12px;">
+<div style="background: #eee; padding: 2px;"><code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/base/nsIConsoleService.idl" rel="custom">xpcom/base/nsIConsoleService.idl</a></code><span style="text-align: right; float: right;"><a href="/zh-CN/docs/Interfaces/About_Scriptable_Interfaces" style="color: #00cc00; font-weight: 700;">脚本化</a></span></div>
+<span style="padding: 4px 2px;">
+
+console service是<a title="en/Error_Console">Error Console</a> 后端的一部分, 与每一个Mozilla应用绑定在一起. 它用来记录各种消息、警告以及错误,同时可获取所有已经记录的消息
+</span>
+
+<div style="background: #eee; padding: 2px;">
+继承于: <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupports" title="">nsISupports</a></code>
+<span style="text-align: right; float: right;">最后修改于Gecko 1.9 (Firefox 3)</span></div>
+</div><p></p>
+<p>实现方式: <code>@mozilla.org/consoleservice;1</code> as a service:</p>
+<pre class="eval">var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
+ .getService(Components.interfaces.nsIConsoleService);
+</pre>
+<h2 id="Method_overview" name="Method_overview">Method overview</h2>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>void <a href="#getMessageArray()">getMessageArray</a>([array, size_is(count)] out nsIConsoleMessage messages, out uint32_t count);</code><span class="inlineIndicator obsolete obsoleteInline" title="(Firefox 19 / Thunderbird 19 / SeaMonkey 2.16)">已废弃 Gecko 19</span><br>
+ <code>void <a href="#getMessageArray()">getMessageArray</a>(</code><code>[optional] out uint32_t count, </code><code>[retval, array, size_is(count)] out nsIConsoleMessage messages);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#logMessage()">logMessage</a>(in nsIConsoleMessage message);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#logStringMessage()">logStringMessage</a>(in wstring message);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#registerListener()">registerListener</a>(in nsIConsoleListener listener);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#reset()">reset</a>();</code> </td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#unregisterListener()">unregisterListener</a>(in nsIConsoleListener listener);</code></td>
+ </tr>
+ </tbody>
+</table>
+<h2 id="Methods" name="Methods">Methods</h2>
+<h3 id="getMessageArray()" name="getMessageArray()">getMessageArray()</h3>
+<p>获取有关目前所有控制台记录的信息的数组</p>
+<p></p><div class="blockIndicator obsolete obsoleteHeader"><p><strong><span class="icon-only-inline" title="This is an obsolete API and is no longer guaranteed to work."><i class="icon-trash"> </i></span> 已废弃 Gecko 19 (Firefox 19 / Thunderbird 19 / SeaMonkey 2.16)</strong><br>This feature is obsolete. Although it may still work in some browsers, its use is discouraged since it could be removed at any time. Try to avoid using it.</p></div><p></p>
+<pre class="eval">void getMessageArray(
+ [array, size_is(count)] out nsIConsoleMessage messages,
+ out PRUint32 count
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>messages</code></dt>
+ <dd>
+ 已经记录的消息数组</dd>
+ <dt>
+ <code>count</code></dt>
+ <dd>
+ 数组中消息的数。如果没有消息被记录,函数会返回0,但同时仍会为message分配一个标记,在从脚本调用时,表示返回的一个长度为0的消息。</dd>
+</dl>
+<p></p>
+<pre class="eval">void getMessageArray(
+ [optional] out PRUint32 count,
+ [retval, array, size_is(count)] out nsIConsoleMessage messages
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>count</code></dt>
+ <dd>
+ The number of messages in the array. If no messages are logged, this function will return a count of 0 but still will allocate one word for messages, so as to show up as a 0-length array when called from script.</dd>
+</dl>
+<p></p><div class="blockIndicator note"><strong>Note:</strong> See the code samples below for how to call getMessageArray.</div><p></p>
+<h3 id="logMessage()" name="logMessage()">logMessage()</h3>
+<pre class="eval">void logMessage(
+ in nsIConsoleMessage message
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>message</code></dt>
+ <dd>
+ An <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIConsoleMessage" title="">nsIConsoleMessage</a></code> to log.</dd>
+</dl>
+<h3 id="logStringMessage()" name="logStringMessage()">logStringMessage()</h3>
+<p>Convenience method for logging simple messages.</p>
+<pre class="eval">void logStringMessage(
+ in wstring message
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>message</code></dt>
+ <dd>
+ The string to log.</dd>
+</dl>
+<h3 id="registerListener()" name="registerListener()">registerListener()</h3>
+<p>Registers a listener for notification when an error is logged.</p>
+<p></p><div class="blockIndicator note"><strong>Note:</strong> To guard against stack overflows from listeners that could log messages (it is easy to do this inadvertently from listeners implemented in JavaScript), we do not call any listeners when another error is already being logged.</div><p></p>
+<pre class="eval">void registerListener(
+ in nsIConsoleListener listener
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>listener</code></dt>
+ <dd>
+ The <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIConsoleListener" title="">nsIConsoleListener</a></code> to add.</dd>
+</dl>
+<p></p><h3 id="reset()">reset()</h3><p></p>
+<p>Clear the message buffer (For example, for privacy reasons).</p>
+<pre class="eval">void reset();
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<p>None.</p>
+<p></p><div class="blockIndicator note"><strong>Note:</strong> Console listeners expect you to log an empty string message before calling <code>reset</code> so that they can clear their message buffers too. (This works before Gecko 1.9 too of course.)</div><p></p>
+<h3 id="unregisterListener()" name="unregisterListener()">unregisterListener()</h3>
+<p>Unregisters a listener.</p>
+<pre class="eval">void unregisterListener(
+ in nsIConsoleListener listener
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>listener</code></dt>
+ <dd>
+ The <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIConsoleListener" title="">nsIConsoleListener</a></code> to remove.</dd>
+</dl>
+<h2 id="Examples" name="Examples">Examples</h2>
+<h4 id="Retrieving_the_message_array" name="Retrieving_the_message_array">Retrieving the message array</h4>
+<p>To retrieve the message array in Gecko prior to version 19:</p>
+<pre class="brush: js">function getConsoleMessageArray() {
+ var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
+ .getService(Components.interfaces.nsIConsoleService);
+ var array = {};
+ consoleService.getMessageArray(array, {});
+ return array.value;
+}
+</pre>
+<p>To retrieve the message array in Gecko 19 or later:</p>
+<pre class="brush: js">function getConsoleMessageArray() {
+ var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
+ .getService(Components.interfaces.nsIConsoleService);
+ return consoleService.getMessageArray();
+}
+</pre>
+<p>To retrieve the message array in a compatible way:</p>
+<pre class="brush: js">function getConsoleMessageArray() {
+ var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
+ .getService(Components.interfaces.nsIConsoleService);
+ var array = {};
+ return consoleService.getMessageArray(array, {}) || array.value;
+}
+</pre>
+<h4 id="Logging_a_simple_message" name="Logging_a_simple_message">Logging a simple message</h4>
+<p>A common usage is to log a string message to console:</p>
+<pre class="brush: js">function LOG(msg) {
+ var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
+ .getService(Components.interfaces.nsIConsoleService);
+ consoleService.logStringMessage(msg);
+}
+</pre>
+<p>Alternative logging methods include <a href="/en/Components.utils.reportError" title="en/Components.utils.reportError">Components.utils.reportError</a> and <a href="/en/DOM/window.dump" title="en/DOM/window.dump">dump()</a>.</p>
+<h4 id="Logging_a_message_with_additional_information" name="Logging_a_message_with_additional_information">Logging a message with additional information</h4>
+<p>To include other information an <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIConsoleMessage" title="">nsIConsoleMessage</a></code> object must be used. In this example <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIScriptError" title="">nsIScriptError</a></code>, which implements <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIConsoleMessage" title="">nsIConsoleMessage</a></code>, is used to include information about the source file and line number of the error.</p>
+<pre class="brush: js">function myLogToConsole(aMessage, aSourceName, aSourceLine, aLineNumber,
+ aColumnNumber, aFlags, aCategory)
+{
+ var consoleService = Components.classes["@mozilla.org/consoleservice;1"]
+ .getService(Components.interfaces.nsIConsoleService);
+ var scriptError = Components.classes["@mozilla.org/scripterror;1"]
+ .createInstance(Components.interfaces.nsIScriptError);
+ scriptError.init(aMessage, aSourceName, aSourceLine, aLineNumber,
+ aColumnNumber, aFlags, aCategory);
+ consoleService.logMessage(scriptError);
+}
+</pre>
+<ul>
+ <li><code>aMessage</code> — the string to be logged. You must provide this.</li>
+ <li><code>aSourceName</code> — the URL of file with error. This will be a hyperlink in the Error Console, so you'd better use real URL. You may pass <code>null</code> if it's not applicable.</li>
+ <li><code>aSourceLine</code> — the line #<code>aLineNumber</code> from <code>aSourceName</code> file. You are responsible for providing that line. You may pass <code>null</code> if you are lazy; that will prevent showing the source line in Error Console.</li>
+ <li><code>aLineNumber</code> and <code>aColumnNumber</code> — specify the exact location of error. <code>aColumnNumber</code> is used to draw the arrow pointing to the problem character.</li>
+ <li><code>aFlags</code> — one of flags declared in <code>nsIScriptError</code>. At the time of writing, possible values are:
+ <ul>
+ <li><code>nsIScriptError.errorFlag = 0</code></li>
+ <li><code>nsIScriptError.warningFlag = 1</code></li>
+ <li><code>nsIScriptError.exceptionFlag = 2</code> and</li>
+ <li><code>nsIScriptError.strictFlag = 4</code>.</li>
+ </ul>
+ </li>
+ <li><code>aCategory</code> — a string indicating what kind of code caused the message. There are quite a few category strings and they do not seem to be listed in a single place. Hopefully, they will all be listed in <code>nsIScriptError.idl</code> eventually.</li>
+</ul>
+<h2 id="See_also" name="See_also">See also</h2>
+<ul>
+ <li><a href="/en/Error_Console" title="en/Error_Console">Error Console</a></li>
+ <li><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIConsoleMessage" title="">nsIConsoleMessage</a></code></li>
+</ul>
+<p></p>
+<div id="cke_pastebin" style="position: absolute; top: 894.333px; width: 1px; height: 1px; overflow: hidden; left: -1000px;">
+  </div>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsidirectoryserviceprovider/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsidirectoryserviceprovider/index.html
new file mode 100644
index 0000000000..20d094eaf3
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsidirectoryserviceprovider/index.html
@@ -0,0 +1,65 @@
+---
+title: nsIDirectoryServiceProvider
+slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIDirectoryServiceProvider
+translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIDirectoryServiceProvider
+---
+<p></p><div style="border: solid #ddd 2px; margin-bottom: 12px;">
+<div style="background: #eee; padding: 2px;"><code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/io/nsIDirectoryService.idl" rel="custom">xpcom/io/nsIDirectoryService.idl</a></code><span style="text-align: right; float: right;"><a href="/zh-CN/docs/Interfaces/About_Scriptable_Interfaces" style="color: #00cc00; font-weight: 700;">脚本化</a></span></div>
+<span style="padding: 4px 2px;">
+
+本接口是目录服务用于得到文件位置的函数。
+</span>
+
+<div style="background: #eee; padding: 2px;">
+继承于: <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupports" title="">nsISupports</a></code>
+<span style="text-align: right; float: right;">最后修改于Gecko 1.7 </span></div>
+</div><p></p>
+<p><code>nsIDirectoryServiceProvider</code>.</p>
+<h2 id="Method_overview" name="Method_overview">方法概览</h2>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>nsIFile <a href="#getFile()">getFile</a>(in string prop, out PRBool persistent);</code></td>
+ </tr>
+ </tbody>
+</table>
+<h2 id="Methods" name="Methods">方法</h2>
+<h3 id="getFile()" name="getFile()">getFile()</h3>
+<p>The Directory Service calls this method when it gets the first request for a prop or on every request if the prop is not persistent.</p>
+<pre class="eval">nsIFile getFile(
+ in string prop,
+ out PRBool persistent
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>prop</code></dt>
+ <dd>
+ The symbolic name of the file.</dd>
+ <dt>
+ <code>persistent</code></dt>
+ <dd>
+ <code>true</code> if the returned file will be cached by Directory Service. Subsequent requests for this prop will bypass the provider and use the cache. <code>false</code> if the provider will be asked for this prop each time it is requested.</dd>
+</dl>
+<h6 id="Return_value" name="Return_value">Return value</h6>
+<p>The <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFile" title="">nsIFile</a></code> represented by the property.</p>
+<h2 id="Example" name="Example">示例</h2>
+<p>This code creates a global, read-only string called <code>currDir</code> with the value of the current working directory.</p>
+<pre class="eval"> __defineGetter__("currDir",
+ function getCurrDir() {
+ return Components.classes["@mozilla.org/file/directory_service;1"]
+ .getService(Components.interfaces.nsIDirectoryServiceProvider)
+ .getFile("CurWorkD",{}).path;
+ });
+</pre>
+<p>Test it with to see the magic happen.</p>
+<pre class="eval"> alert(currDir);
+</pre>
+<h2 id="See_also" name="See_also">参见</h2>
+<ul>
+ <li><a href="/en/nsDirectoryService" title="en/nsDirectoryService">nsDirectoryService</a></li>
+ <li><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDirectoryService" title="">nsIDirectoryService</a></code></li>
+ <li>(译注)其它目录服务关键字见<a href="http://mxr.mozilla.org/mozilla-central/source/xpcom/io/nsDirectoryServiceDefs.h" title="http://mxr.mozilla.org/mozilla-central/source/xpcom/io/nsDirectoryServiceDefs.h">nsDirectoryServiceDefs.h</a></li>
+</ul>
+<p>Additionally, see <a class="external" href="http://mb.eschew.org/16.php#sub_16.5.2">section 16.5.2</a> of the <a class="external" href="http://mb.eschew.org/">Rapid Application Development with Mozilla</a> book for instructions on how to get the <strong>current working directory</strong> and the <strong>process binary directory</strong>, among other things.</p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsidomclientrect/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsidomclientrect/index.html
new file mode 100644
index 0000000000..20a00c9e26
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsidomclientrect/index.html
@@ -0,0 +1,92 @@
+---
+title: nsIDOMClientRect
+slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMClientRect
+translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMClientRect
+---
+<p></p><div style="border: solid #ddd 2px; margin-bottom: 12px;">
+<div style="background: #eee; padding: 2px;"><code><a href="https://dxr.mozilla.org/mozilla-central/source/dom/interfaces/base/nsIDOMClientRect.idl" rel="custom">dom/interfaces/base/nsIDOMClientRect.idl</a></code><span style="text-align: right; float: right;"><a href="/zh-CN/docs/Interfaces/About_Scriptable_Interfaces" style="color: #00cc00; font-weight: 700;">脚本化</a></span></div>
+<span style="padding: 4px 2px;">代表一个矩形盒子。盒子类型由返回这种盒子对象的方法指定的。它是由像<a href="/zh-CN/docs/Web/API/Element/getBoundingClientRect" title="Element.getBoundingClientRect()方法返回元素的大小及其相对于视口的位置。"><code>element.getBoundingClientRect</code></a>的函数返回的。.</span>
+
+ <div style="height: 42px; position: relative; padding: 2px; width: auto;">
+
+ <div style="top: 22px; font-size: 11px; position: absolute;">1.0</div>
+
+ <div style="top: 22px; font-size: 11px; position: absolute; left: 0px; text-align: right; float: right; width: 100%;">66</div>
+
+ <div style="height: 8px; top: 16px; background: #dd0000; left: 0px; position: absolute; width: 8.571428571428571%;"></div>
+
+<div style="height: 8px; top: 16px; left: 8.571428571428571%; background: #00dd00; position: absolute; width: 91.42857142857143%;" title="Introduced in Gecko 1.9 (Firefox 3)"></div>
+
+<div style="top: 0px; font-size: 11px; position: absolute; left: 8.571428571428571%;">Introduced</div>
+<div style="top: 22px; font-size: 11px; position: absolute; left: 8.571428571428571%;">Gecko 1.9</div>
+
+ <div style="height: 8px; top: 16px; left: 9.023809428571429%; background: #eeee00; position: absolute; width: 1%; border-radius: 4px; -webkit-border-radius: 4px;" title="Last changed in Gecko 1.9.1 (Firefox 3.5 / Thunderbird 3.0 / SeaMonkey 2.0)"></div>
+
+</div>
+
+<div style="background: #eee; padding: 2px;">
+继承于: <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupports" title="">nsISupports</a></code>
+<span style="text-align: right; float: right;">最后修改于Gecko 1.9.1 (Firefox 3.5 / Thunderbird 3.0 / SeaMonkey 2.0)</span></div>
+</div><p></p>
+
+<h2 id="Attributes" name="Attributes">属性</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">Attribute</td>
+ <td class="header">Type</td>
+ <td class="header">Description</td>
+ </tr>
+ <tr>
+ <td><code>bottom</code></td>
+ <td><code><a href="/en/float" title="en/float">float</a></code></td>
+ <td>Y 轴,相对于视口原点(viewport origin)矩形盒子的底部。<strong>只读。 </strong></td>
+ </tr>
+ <tr>
+ <td><code>height</code></td>
+ <td><code><a href="/en/float" title="en/float">float</a></code></td>
+ <td>矩形盒子的高度(等同于 bottom 减 top)。<strong>只读。</strong></td>
+ </tr>
+ <tr>
+ <td><code>left</code></td>
+ <td><code><a href="/en/float" title="en/float">float</a></code></td>
+ <td>X 轴,相对于视口原点(viewport origin)矩形盒子的左侧。<strong>只读。 </strong></td>
+ </tr>
+ <tr>
+ <td><code>right</code></td>
+ <td><code><a href="/en/float" title="en/float">float</a></code></td>
+ <td>X 轴,相对于视口原点(viewport origin)矩形盒子的右侧。<strong>只读。 </strong></td>
+ </tr>
+ <tr>
+ <td><code>top</code></td>
+ <td><code><a href="/en/float" title="en/float">float</a></code></td>
+ <td>Y 轴,相对于视口原点(viewport origin)矩形盒子的顶部。<strong>只读。</strong></td>
+ </tr>
+ <tr>
+ <td><code>width</code></td>
+ <td><code><a href="/en/float" title="en/float">float</a></code></td>
+ <td>矩形盒子的宽度(等同于 right 减 left)。<strong>只读。</strong> </td>
+ </tr>
+ <tr>
+ <td><code>x</code></td>
+ <td><code><a href="/en/float" title="en/float">float</a></code></td>
+ <td>X 轴,相对于视口原点(viewport origin)矩形盒子的左侧。<strong>只读。</strong> </td>
+ </tr>
+ <tr>
+ <td><code>y</code></td>
+ <td><code><a href="/en/float" title="en/float">float</a></code></td>
+ <td>Y 轴,相对于视口原点(viewport origin)矩形盒子的顶部。<strong>只读。</strong></td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="See_also" name="See_also">参考资料</h2>
+
+<ul>
+ <li><a href="http://www.w3.org/TR/cssom-view/#the-clientrect-interface">CSSOM View Module : The ClientRect Interface</a><span style="color: #fff; background: #e66e33; display: inline-block; font-size: x-small; margin-left: 6px; white-space: nowrap; padding: 2px 5px;" title="工作草案">WD</span></li>
+</ul>
+
+<p><span style="line-height: 1.5;">这个对象几次易名:最初叫做 TextRectangle,</span><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=916520" style="line-height: 1.5;">然后</a><span style="line-height: 1.5;">叫做 ClientRect,</span><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=916520" style="line-height: 1.5;">后来</a><span style="line-height: 1.5;">叫做 DOMRect。</span></p>
+
+<p><span style="line-height: 1.5;">该对象最初只有 top、left、right、bottom 属性,后来添加了 width、height、x、y 属性。</span></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsifile/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsifile/index.html
new file mode 100644
index 0000000000..d966771e83
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsifile/index.html
@@ -0,0 +1,828 @@
+---
+title: nsIFile
+slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIFile
+translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIFile
+---
+<p></p><div style="border: solid #ddd 2px; margin-bottom: 12px;">
+<div style="background: #eee; padding: 2px;"><code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/io/nsIFile.idl" rel="custom">xpcom/io/nsIFile.idl</a></code><span style="text-align: right; float: right;"><a href="/zh-CN/docs/Interfaces/About_Scriptable_Interfaces" style="color: #00cc00; font-weight: 700;">脚本化</a></span></div>
+<span style="padding: 4px 2px;">
+
+An instance of this interface is a cross-platform representation of a location in the filesystem.
+</span>
+
+<div style="background: #eee; padding: 2px;">
+继承于: <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupports" title="">nsISupports</a></code>
+<span style="text-align: right; float: right;">最后修改于Gecko 1.0 </span></div>
+</div><p></p>
+<p><code>nsIFile</code> is the correct platform-agnostic way to specify a file; you should always use this instead of a string to ensure compatibility.</p>
+<p>With an <code>nsIFile</code> you can navigate to ancestors or descendants without having to deal with the different path separators used on different platforms, query the state of any file or directory at the position represented by the <code>nsIFile</code> and create, move or copy items in the filesystem.</p>
+<p>An <code>nsIFile</code> can be retrieved by either instantiating an <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsILocalFile" title="">nsILocalFile</a></code> using a platform specific path string or by using cross-platform locations retrieved from the <a href="/en/Code_snippets/File_I//O#Getting_special_files" title="en/Code_snippets/File_I//O#Getting_special_files">directory service</a>.</p>
+<p>All methods with string parameters have two forms. The preferred form operates on UTF-16 encoded characters strings. An alternate form operates on characters strings encoded in the "native" charset. A string containing characters encoded in the native charset cannot be safely passed to javascript via xpconnect. Therefore, the UTF-16 forms are scriptable, but the "native methods" are not. In addition, the native form <strong>cannot</strong> deal with files whose name contains characters outside the default system code page on Windows. Using the native form limits the ability of your code to deal with the full Unicode support on Windows 2000 or later where the OS itself does not have such a limitation. Therefore, you <strong>must not</strong> use the native form unless it is <strong>guaranteed</strong> that the path passed to a native form function is <strong>always</strong> ASCII.</p>
+<div class="note">
+ <strong>Note:</strong> <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsILocalFile" title="">nsILocalFile</a></code> was merged with this interface in Gecko 14. Much of the documentation has not been updated to reflect this change.</div>
+<h2 id="Method_overview" name="Method_overview">Method overview</h2>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>void <a href="#append()">append</a>(in AString node);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#appendNative()">appendNative</a>(in ACString node);</code> <span class="inlineIndicator noscript noscriptInline" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="/en/XPCOM_Interface_Reference/nsILocalFile#appendRelativeNativePath()" title="/en/XPCOM_Interface_Reference/nsILocalFile#appendRelativeNativePath()">appendRelativeNativePath</a>(in ACString relativeFilePath);</code> <span class="inlineIndicator noscript noscriptInline" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="/en/XPCOM_Interface_Reference/nsILocalFile#appendRelativePath()" title="/en/XPCOM_Interface_Reference/nsILocalFile#appendRelativePath()">appendRelativePath</a>(in AString relativeFilePath);</code> </td>
+ </tr>
+ <tr>
+ <td><code>nsIFile <a href="#clone()">clone</a>();</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#contains()">contains</a>(in nsIFile inFile, in boolean recur);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#copyTo()">copyTo</a>(in nsIFile newParentDir, in AString newName);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#copyToFollowingLinks()">copyToFollowingLinks</a>(in nsIFile newParentDir, in AString newName);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#copyToFollowingLinksNative()">copyToFollowingLinksNative</a>(in nsIFile newParentDir, in ACString newName);</code> <span class="inlineIndicator noscript noscriptInline" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#CopyToNative()">CopyToNative</a>(in nsIFile newParentDir, in ACString newName);</code> <span class="inlineIndicator noscript noscriptInline" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#create()">create</a>(in unsigned long type, in unsigned long permissions);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#createUnique()">createUnique</a>(in unsigned long type, in unsigned long permissions);</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#equals()">equals</a>(in nsIFile inFile);</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#exists()">exists</a>();</code></td>
+ </tr>
+ <tr>
+ <td><code>ACString <a href="/en/XPCOM_Interface_Reference/nsILocalFile#getRelativeDescriptor()" title="/en/XPCOM_Interface_Reference/nsILocalFile#getRelativeDescriptor()">getRelativeDescriptor</a>(in nsIFile fromFile);</code> </td>
+ </tr>
+ <tr>
+ <td><code>void <a href="/en/XPCOM_Interface_Reference/nsILocalFile#initWithFile()" title="/en/XPCOM_Interface_Reference/nsILocalFile#initWithFile()">initWithFile</a>(in nsIFile aFile);</code> </td>
+ </tr>
+ <tr>
+ <td><code>void <a href="/en/XPCOM_Interface_Reference/nsILocalFile#initWithNativePath()" title="/en/XPCOM_Interface_Reference/nsILocalFile#initWithNativePath()">initWithNativePath</a>(in ACString filePath);</code> <span class="inlineIndicator noscript noscriptInline" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="/en/XPCOM_Interface_Reference/nsILocalFile#initWithPath()" title="/en/XPCOM_Interface_Reference/nsILocalFile#initWithPath()">initWithPath</a>(in AString filePath);</code> </td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#isDirectory()">isDirectory</a>();</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#isExecutable()">isExecutable</a>();</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#isFile()">isFile</a>();</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#isHidden()">isHidden</a>();</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#isReadable()">isReadable</a>();</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#isSpecial()">isSpecial</a>();</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#isSymlink()">isSymlink</a>();</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#isWritable()">isWritable</a>();</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="/en/XPCOM_Interface_Reference/nsILocalFile#launch()" title="/en/XPCOM_Interface_Reference/nsILocalFile#launch()">launch</a>();</code> </td>
+ </tr>
+ <tr>
+ <td><code>PRLibraryStar <a href="/en/XPCOM_Interface_Reference/nsILocalFile#load()" title="/en/XPCOM_Interface_Reference/nsILocalFile#load()">load</a>();</code> <span class="inlineIndicator noscript noscriptInline" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#moveTo()">moveTo</a>(in nsIFile newParentDir, in AString newName);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#moveToNative()">moveToNative</a>(in nsIFile newParentDir, in ACString newName);</code> <span class="inlineIndicator noscript noscriptInline" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#normalize()">normalize</a>();</code></td>
+ </tr>
+ <tr>
+ <td><code>FILE <a href="/en/XPCOM_Interface_Reference/nsILocalFile#openANSIFileDesc()" title="/en/XPCOM_Interface_Reference/nsILocalFile#openANSIFileDesc()">openANSIFileDesc</a>(in string mode);</code> <span class="inlineIndicator noscript noscriptInline" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span></td>
+ </tr>
+ <tr>
+ <td><code>PRFileDescStar <a href="/en/XPCOM_Interface_Reference/nsILocalFile#openNSPRFileDesc()" title="/en/XPCOM_Interface_Reference/nsILocalFile#openNSPRFileDesc()">openNSPRFileDesc</a>(in long flags, in long mode);</code> <span class="inlineIndicator noscript noscriptInline" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#remove()">remove</a>(in boolean recursive);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="/en/XPCOM_Interface_Reference/nsILocalFile#reveal()" title="/en/XPCOM_Interface_Reference/nsILocalFile#reveal()">reveal</a>();</code> </td>
+ </tr>
+ <tr>
+ <td><code>void <a href="/en/XPCOM_Interface_Reference/nsILocalFile#setRelativeDescriptor()" title="/en/XPCOM_Interface_Reference/nsILocalFile#setRelativeDescriptor()">setRelativeDescriptor</a>(in nsIFile fromFile, in ACString relativeDesc);</code> </td>
+ </tr>
+ </tbody>
+</table>
+<h2 id="Attributes" name="Attributes">Attributes</h2>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">Attribute</td>
+ <td class="header">Type</td>
+ <td class="header">Description</td>
+ </tr>
+ <tr>
+ <td><code>directoryEntries</code></td>
+ <td><code><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISimpleEnumerator" title="">nsISimpleEnumerator</a></code></code></td>
+ <td>Returns an enumeration of the elements in a directory. Each element in the enumeration is an <code>nsIFile</code>. <strong>Read only.</strong>
+ <h6 id="Exceptions_thrown" name="Exceptions_thrown">Exceptions thrown</h6>
+ <dl>
+ <dt>
+ <code>NS_ERROR_FILE_NOT_DIRECTORY</code></dt>
+ <dd>
+ Indicates that this <code>nsIFile</code> does not reference a directory.</dd>
+ </dl>
+ </td>
+ </tr>
+ <tr>
+ <td><code>diskSpaceAvailable</code> </td>
+ <td><code><a href="/en/PRInt64" title="en/PRInt64">PRInt64</a></code></td>
+ <td>The number of bytes available to non-superuser on the disk volume containing the <code>nsIFile</code>. <strong>Read only.</strong></td>
+ </tr>
+ <tr>
+ <td><code>fileSize</code></td>
+ <td><code><a href="/en/PRInt64" title="en/PRInt64">PRInt64</a></code></td>
+ <td>
+ <p>The value of this attribute is the number of bytes corresponding to the data represented by the file.</p>
+ <p>On the Mac, getting/setting the file size with <code>nsIFile</code> only deals with the size of the data fork. If you need to know the size of the combined data and resource forks use <code><a href="https://developer.mozilla.org/zh-CN/docs/XPCOM_Interface_Reference/nsILocalFileMac#GetFileSizeWithResFork()">nsILocalFileMac.GetFileSizeWithResFork()</a></code>.</p>
+ Changing the size of a <code>nsIFile</code> operates on the underlying filesystem, possibly truncating the existing file to specified size.</td>
+ </tr>
+ <tr>
+ <td><code>fileSizeOfLink</code></td>
+ <td><code><a href="/en/PRInt64" title="en/PRInt64">PRInt64</a></code></td>
+ <td>
+ <p>This attribute exposes the size of the symbolic link referenced by this <code>nsIFile</code>.</p>
+ <p>Unlike <code>fileSize</code>, this attribute corresponds to the size of the symbolic link referenced by this <code>nsIFile</code>. If this <code>nsIFile</code> does not reference a symbolic link, then the value of this attribute is undefined.</p>
+ The value of this attribute is the number of bytes corresponding to the data represented by the symbolic link. Any meta data, such as a resource fork on the Mac, is not included in the measurement of the file size. <strong>Read only.</strong></td>
+ </tr>
+ <tr>
+ <td><code>followLinks</code> </td>
+ <td><code><a href="/en/PRBool" title="en/PRBool">PRBool</a></code></td>
+ <td>
+ <p>Determines whether or not the <code>nsIFile</code> will automatically resolve symbolic links.</p>
+ By default, this value is <code>false</code> on all non-UNIX systems. As of Mozilla 1.7, this attribute is ignored on UNIX systems.</td>
+ </tr>
+ <tr>
+ <td><code>lastModifiedTime</code></td>
+ <td><code><a href="/en/PRInt64" title="en/PRInt64">PRInt64</a></code></td>
+ <td>
+ <p>This attribute exposes the time when the file referenced by this <code>nsIFile</code> was last modified.</p>
+ <p>The value of this attribute is milliseconds since midnight (00:00:00), January 1, 1970 Greenwich Mean Time (GMT).</p>
+ Changing the last modified time of a <code>nsIFile</code> operates on the underlying filesystem. As of <span title="">Gecko 1.7</span>, changing the last modified time of a non-existent file has undefined behavior.</td>
+ </tr>
+ <tr>
+ <td><code>lastModifiedTimeOfLink</code></td>
+ <td><code><a href="/en/PRInt64" title="en/PRInt64">PRInt64</a></code></td>
+ <td>
+ <p>This attribute exposes the time when the symbolic link referenced by this <code>nsIFile</code> was last modified.</p>
+ <p>Unlike <code>lastModifiedTime</code>, this attribute corresponds to the last modified time of the symbolic link referenced by this <code>nsIFile</code>. If this <code>nsIFile</code> does not reference a symbolic link, then the value of this attribute is undefined.</p>
+ <p>The value of this attribute is milliseconds since midnight (00:00:00), January 1, 1970 Greenwich Mean Time (GMT).</p>
+ Changing the last modified time of a <code>nsIFile</code> operates on the underlying filesystem. As of <span title="">Gecko 1.7</span>, changing the last modified time of a non-existent file has undefined behavior.</td>
+ </tr>
+ <tr>
+ <td><code>leafName</code></td>
+ <td><code><a href="/en/AString" title="en/AString">AString</a></code></td>
+ <td>
+ <p>This attribute exposes the name of the <code>nsIFile</code> without any directory components.</p>
+ Changing the leaf name of a <code>nsIFile</code> does not affect the underlying filesystem. It only changes what this <code>nsIFile</code> references.</td>
+ </tr>
+ <tr>
+ <td><code>nativeLeafName</code></td>
+ <td><code><a href="/en/ACString" title="en/ACString">ACString</a></code></td>
+ <td>
+ <p>This attribute exposes the name of the <code>nsIFile</code> without any directory components. [native character encoding variant]</p>
+ Changing the leaf name of a <code>nsIFile</code> does not affect the underlying filesystem. It only changes what this <code>nsIFile</code> references. <span class="inlineIndicator noscript noscriptInline" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span></td>
+ </tr>
+ <tr>
+ <td><code>nativePath</code></td>
+ <td><code><a href="/en/ACString" title="en/ACString">ACString</a></code></td>
+ <td>
+ <p>This attribute exposes the full path of the <code>nsIFile</code>. [native character encoding variant]</p>
+ The value of this attribute is a platform-specific file path. <strong>Read only.</strong> <span class="inlineIndicator noscript noscriptInline" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span></td>
+ </tr>
+ <tr>
+ <td><code>nativeTarget</code></td>
+ <td><code><a href="/en/ACString" title="en/ACString">ACString</a></code></td>
+ <td>
+ <p>This attribute exposes the full target of the <code>nsIFile</code> - the full path with any symbolic links dereferenced. [native character encoding variant]</p>
+ The value of this attribute is a platform-specific file path. <strong>Read only.</strong> <span class="inlineIndicator noscript noscriptInline" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span></td>
+ </tr>
+ <tr>
+ <td><code>parent</code></td>
+ <td><code><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFile" title="">nsIFile</a></code></code></td>
+ <td>
+ <p>This attribute returns the parent <code>nsIFile</code> for this <code>nsIFile</code>.</p>
+ The parent will be <code>null</code> when this <code>nsIFile</code> references the top of the volume. For example, C:\ does not have a parent. <strong>Read only.</strong></td>
+ </tr>
+ <tr>
+ <td><code>path</code></td>
+ <td><code><a href="/en/AString" title="en/AString">AString</a></code></td>
+ <td>
+ <p>This attribute exposes the full platform-specific path of the <code>nsIFile</code> (including the <code>leafName</code>). <strong>Read only.</strong></p>
+ Example, this could return "/home/user/foo.txt" or "C:\Images\my.jpeg"</td>
+ </tr>
+ <tr>
+ <td><code>permissions</code></td>
+ <td><code><a href="/en/unsigned_long" title="en/unsigned long">unsigned long</a></code></td>
+ <td>
+ <p>The value of this attribute is a UNIX-style file permission mask for this <code>nsIFile</code>.</p>
+ Changing the permissions of a <code>nsIFile</code> operates on the underlying filesystem. As of <span title="">Gecko 1.7</span>, changing the permissions of a non-existent file has undefined behavior.</td>
+ </tr>
+ <tr>
+ <td><code>permissionsOfLink</code></td>
+ <td><code><a href="/en/unsigned_long" title="en/unsigned long">unsigned long</a></code></td>
+ <td>
+ <p>The value of this attribute is a UNIX-style file permission mask for this <code>nsIFile</code>.</p>
+ <p>Unlike <code>permissions</code>, this attribute corresponds to the permissions of the symbolic link referenced by this <code>nsIFile</code>. If this <code>nsIFile</code> does not reference a symbolic link, then the value of this attribute is undefined.</p>
+ Changing the permissions of a <code>nsIFile</code> operates on the underlying filesystem. As of <span title="">Gecko 1.7</span>, changing the permissions of a non-existent file has undefined behavior.</td>
+ </tr>
+ <tr>
+ <td><code>persistentDescriptor</code> </td>
+ <td><code><a href="/en/ACString" title="en/ACString">ACString</a></code></td>
+ <td>
+ <p>On some platforms, the value of <a href="https://developer.mozilla.org/zh-CN/docs/XPCOM_Interface_Reference/nsIFile#path">nsIFile.path</a> may be insufficient to uniquely identify the file on the local file system. The persistent descriptor is intended to be used whenever a <code>nsIFile</code> needs to be serialized to disk and later recovered. This string is not intended for display to users.</p>
+ <div class="blockIndicator note"><strong>Note:</strong> The value of the <code>followLinks</code> attribute is not encoded in the persistent descriptor.</div></td>
+ </tr>
+ <tr>
+ <td><code>target</code></td>
+ <td><code><a href="/en/AString" title="en/AString">AString</a></code></td>
+ <td>
+ <p>This attribute exposes the full target of the <code>nsIFile</code> - the full path with any symbolic links dereferenced.</p>
+ <p>Accessor to the string <code>path</code>. The native version of these strings are not guaranteed to be a usable <code>path</code> to pass to NSPR or the C stdlib. There are problems that affect platforms on which a <code>path</code> does not fully specify a file because two volumes can have the same name (For example Mac). This is solved by holding "private", native data in the <code>nsIFile</code> implementation. This native data is lost when you convert to a string. DO NOT PASS TO USE WITH NSPR OR STDLIB! <strong>Read only.</strong></p>
+ <h6 id="Exceptions_thrown" name="Exceptions_thrown">Exceptions thrown</h6>
+ <dl>
+ <dt>
+ <code>NS_ERROR_FILE_INVALID_PATH</code></dt>
+ <dd>
+ Indicates that this <code>nsIFile</code> does not reference a symbolic links.</dd>
+ </dl>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<h2 id="Constants" name="Constants">Constants</h2>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">Constant</td>
+ <td class="header">Value</td>
+ <td class="header">Description</td>
+ </tr>
+ <tr>
+ <td><code>NORMAL_FILE_TYPE</code></td>
+ <td><code>0</code></td>
+ <td>A normal file.</td>
+ </tr>
+ <tr>
+ <td><code>DIRECTORY_TYPE</code></td>
+ <td><code>1</code></td>
+ <td>A directory/folder.</td>
+ </tr>
+ <tr>
+ <td><code>DELETE_ON_CLOSE</code> </td>
+ <td><code>0x80000000</code></td>
+ <td>Optional parameter used by <a href="/en/XPCOM_Interface_Reference/nsILocalFile#openNSPRFileDesc()" title="/en/XPCOM_Interface_Reference/nsILocalFile#openNSPRFileDesc()">openNSPRFileDesc</a></td>
+ </tr>
+ </tbody>
+</table>
+<h2 id="Methods" name="Methods">Methods</h2>
+<h3 id="append()" name="append()">append()</h3>
+<p>This function is used for constructing a descendant of the current <code>nsIFile</code>.</p>
+<div class="note style-wrap">
+ <p><strong>Note:</strong> This method does not return a new <code>nsIFile</code>; it modifies the object it was called on. If the old <code>nsIFile</code> should be retained, use <code><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFile#clone()">clone()</a></code>.</p>
+</div>
+<pre class="eval">void append(
+ in AString node
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>node</code></dt>
+ <dd>
+ A string which is intended to be a child node of the <code>nsIFile</code>. This string must not contain a path separator character.</dd>
+</dl>
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">Exceptions thrown</h6>
+<dl>
+ <dt>
+ <code>NS_ERROR_FILE_UNRECOGNIZED_PATH</code></dt>
+ <dd>
+ Indicates that aNode incorrectly contains a path separator character.</dd>
+</dl>
+<p></p><div><span class="indicatorInHeadline noscript noscriptMethod" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span><h3 id="appendNative">appendNative</h3></div><p></p>
+<p>This method is used for constructing a descendant of the current <code>nsIFile</code>. [native character encoding variant]</p>
+<pre class="eval">void appendNative(
+ in ACString node
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>node</code></dt>
+ <dd>
+ A string that is intended to be a child node of the current <code>nsIFile</code>. This string must not contain a path separator character. This string must be encoded using the native character encoding.</dd>
+</dl>
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">Exceptions thrown</h6>
+<dl>
+ <dt>
+ <code>NS_ERROR_FILE_UNRECOGNIZED_PATH</code></dt>
+ <dd>
+ Indicates that aNode incorrectly contains a path separator character.</dd>
+</dl>
+<h3 id="clone()" name="clone()">clone()</h3>
+<p>This method creates a clone of the <code>nsIFile</code>. (It does NOT clone the file itself; see the copy methods.)</p>
+<pre class="eval">nsIFile clone();
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<p>None.</p>
+<h6 id="Return_value" name="Return_value">Return value</h6>
+<p>A new <code>nsIFile</code> instance that corresponds to the same file or directory as this <code>nsIFile</code>.</p>
+<h3 id="contains()" name="contains()">contains()</h3>
+<p>This method tests whether or not a <code>nsIFile</code> instance is a descendant of the this <code>nsIFile</code>.</p>
+<pre class="eval">boolean contains(
+ in nsIFile inFile,
+ in boolean recur
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>inFile</code></dt>
+ <dd>
+ The <code>nsIFile</code> to test.</dd>
+ <dt>
+ <code>recur</code></dt>
+ <dd>
+ This parameter specifies whether or not subdirectories should be inspected. As of <span title="">Gecko 1.7</span>, this parameter is ignored and always treated as false by the canonical Local File implementation.</dd>
+</dl>
+<h6 id="Return_value" name="Return_value">Return value</h6>
+<p><code>true</code> if inFile is a descendant of this <code>nsIFile</code>.</p>
+<h3 id="copyTo()" name="copyTo()">copyTo()</h3>
+<p>This method copies a source file to a new location if it does not already exist.</p>
+<p>This method will NOT resolve aliases/shortcuts during the copy.</p>
+<pre class="eval">void copyTo(
+ in nsIFile newParentDir,
+ in AString newName
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>newParentDir</code></dt>
+ <dd>
+ This parameter specifies the parent directory to copy the file into. If this parameter is <code>null</code>, then the parent directory of the file will be used.</dd>
+ <dt>
+ <code>newName</code></dt>
+ <dd>
+ This parameter allows you to specify a new leaf name for the file to be copied. This parameter may be empty, in which case the current leaf name will be used.</dd>
+</dl>
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">Exceptions thrown</h6>
+<dl>
+ <dt>
+ <code>NS_ERROR_FILE_DESTINATION_NOT_DIR</code></dt>
+ <dd>
+ If the "newParentDir" is not a directory.</dd>
+ <dt>
+ <code>NS_ERROR_FILE_TARGET_DOES_NOT_EXIST</code></dt>
+ <dd>
+ Indicates that the current file path does not exist. It is not possible to copy a file that does not exist.</dd>
+ <dt>
+ <code>NS_ERROR_FILE_ALREADY_EXISTS</code></dt>
+ <dd>
+ Indicates that there is already a file named "newName" in the destination directory.</dd>
+</dl>
+<h3 id="copyToFollowingLinks()" name="copyToFollowingLinks()">copyToFollowingLinks()</h3>
+<p>This method copies a source file to a new location if it does not already exist.</p>
+<p>This method is identical to <code><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFile#copyTo()">copyTo()</a></code> except that any symbolic links will be followed as the name suggests.</p>
+<pre class="eval">void copyToFollowingLinks(
+ in nsIFile newParentDir,
+ in AString newName
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>newParentDir</code></dt>
+ <dd>
+ This parameter specifies the parent directory to copy the file into. If this parameter is <code>null</code>, then the parent directory of the file will be used.</dd>
+ <dt>
+ <code>newName</code></dt>
+ <dd>
+ This parameter allows you to specify a new leaf name for the file to be copied. This parameter may be empty, in which case the current leaf name will be used.</dd>
+</dl>
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">Exceptions thrown</h6>
+<dl>
+ <dt>
+ <code>NS_ERROR_FILE_DESTINATION_NOT_DIR</code></dt>
+ <dd>
+ If the "newParentDir" is not a directory.</dd>
+ <dt>
+ <code>NS_ERROR_FILE_TARGET_DOES_NOT_EXIST</code></dt>
+ <dd>
+ Indicates that the current file path does not exist. It is not possible to copy a file that does not exist.</dd>
+ <dt>
+ <code>NS_ERROR_FILE_ALREADY_EXISTS</code></dt>
+ <dd>
+ Indicates that there is already a file named "newName" in the destination directory.</dd>
+</dl>
+<p></p><div><span class="indicatorInHeadline noscript noscriptMethod" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span><h3 id="copyToFollowingLinksNative">copyToFollowingLinksNative</h3></div><p></p>
+<p>This method copies this file to a new location. [native character encoding variant]</p>
+<p>This method is identical to <code><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFile#copyToNative()">copyToNative()</a></code> except that any symbolic links will be followed as the name suggests.</p>
+<pre class="eval">void copyToFollowingLinksNative(
+ in nsIFile newParentDir,
+ in ACString newName
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>newParentDir</code></dt>
+ <dd>
+ This parameter specifies the parent directory to copy the file into. If this parameter is <code>null</code>, then the parent directory of the file will be used.</dd>
+ <dt>
+ <code>newName</code></dt>
+ <dd>
+ This parameter allows you to specify a new leaf name for the file to be copied. This parameter may be empty, in which case the current leaf name will be used. This string must be encoded using the native character encoding.</dd>
+</dl>
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">Exceptions thrown</h6>
+<dl>
+ <dt>
+ <code>NS_ERROR_FILE_DESTINATION_NOT_DIR</code></dt>
+ <dd>
+ If the "newParentDir" is not a directory.</dd>
+ <dt>
+ <code>NS_ERROR_FILE_TARGET_DOES_NOT_EXIST</code></dt>
+ <dd>
+ Indicates that the current file path does not exist. It is not possible to copy a file that does not exist.</dd>
+ <dt>
+ <code>NS_ERROR_FILE_ALREADY_EXISTS</code></dt>
+ <dd>
+ Indicates that there is already a file named "newName" in the destination directory.</dd>
+</dl>
+<p></p><div><span class="indicatorInHeadline noscript noscriptMethod" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span><h3 id="CopyToNative">CopyToNative</h3></div><p></p>
+<p>This method copies this file to a new location. [native character encoding variant]</p>
+<pre class="eval">void CopyToNative(
+ in nsIFile newParentDir,
+ in ACString newName
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>newParentDir</code></dt>
+ <dd>
+ This parameter specifies the parent directory to copy the file into. If this parameter is <code>null</code>, then the parent directory of the file will be used.</dd>
+ <dt>
+ <code>newName</code></dt>
+ <dd>
+ This parameter allows you to specify a new leaf name for the file to be copied. This parameter may be empty, in which case the current leaf name will be used. This string must be encoded using the native character encoding.</dd>
+</dl>
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">Exceptions thrown</h6>
+<dl>
+ <dt>
+ <code>NS_ERROR_FILE_DESTINATION_NOT_DIR</code></dt>
+ <dd>
+ If the "newParentDir" is not a directory.</dd>
+ <dt>
+ <code>NS_ERROR_FILE_TARGET_DOES_NOT_EXIST</code></dt>
+ <dd>
+ Indicates that the current file path does not exist. It is not possible to copy a file that does not exist.</dd>
+ <dt>
+ <code>NS_ERROR_FILE_ALREADY_EXISTS</code></dt>
+ <dd>
+ Indicates that there is already a file named "newName" in the destination directory.</dd>
+</dl>
+<h3 id="create()" name="create()">create()</h3>
+<p>This method creates a new file or directory in the file system corresponding to the file path represented by this <code>nsIFile</code>. This method will create any path segments that do not already exist.</p>
+<pre class="eval">void create(
+ in unsigned long type,
+ in unsigned long permissions
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>type</code></dt>
+ <dd>
+ This specifies the type of file system object to be made. The only two types at this time are file and directory which are defined above.</dd>
+ <dt>
+ <code>permissions</code></dt>
+ <dd>
+ A UNIX-style file permissions value. For example, the octal value 0600 may be used to limit read and write access to the current user of the system. This parameter may be ignored on systems that do not support file permissions.</dd>
+</dl>
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">Exceptions thrown</h6>
+<dl>
+ <dt>
+ <code>NS_ERROR_FILE_ALREADY_EXISTS</code></dt>
+ <dd>
+ Indicates that the file or directory already exists.</dd>
+ <dt>
+ <code>NS_ERROR_FILE_UNKNOWN_TYPE</code></dt>
+ <dd>
+ Indicates that the value of "type" does not correspond to a known type.</dd>
+</dl>
+<h3 id="createUnique()" name="createUnique()">createUnique()</h3>
+<p>This function will create a new file or directory in the file system. Any nodes that have not been created or resolved, will be. If this file already exists, we try variations on the leaf name "suggestedName" until we find one that did not already exist. This method will create any path segments that do not already exist.</p>
+<pre class="eval">void createUnique(
+ in unsigned long type,
+ in unsigned long permissions
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>type</code></dt>
+ <dd>
+ This specifies the type of file system object to be made. The only two types at this time are file and directory which are defined above.</dd>
+ <dt>
+ <code>permissions</code></dt>
+ <dd>
+ A UNIX-style file permissions value. For example, the octal value 0600 may be used to limit read and write access to the current user of the system. This parameter may be ignored on systems that do not support file permissions.</dd>
+</dl>
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">Exceptions thrown</h6>
+<dl>
+ <dt>
+ <code>NS_ERROR_FILE_UNKNOWN_TYPE</code></dt>
+ <dd>
+ Indicates that the value of "type" does not correspond to a known type.</dd>
+ <dt>
+ <code>NS_ERROR_FILE_TOO_BIG</code></dt>
+ <dd>
+ Indicates that the search for nonexistent files was unsuccessful because all of the attempted leaf name variants already exist.</dd>
+</dl>
+<h3 id="equals()" name="equals()">equals()</h3>
+<p>This method tests whether or not two <code>nsIFile</code> instances correspond to the same file or directory.</p>
+<pre class="eval">boolean equals(
+ in nsIFile inFile
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>inFile</code></dt>
+ <dd>
+ The <code>nsIFile</code> to compare this <code>nsIFile</code> against.</dd>
+</dl>
+<h6 id="Return_value" name="Return_value">Return value</h6>
+<p><code>true</code> if "inFile" is equivalent to this <code>nsIFile</code>.</p>
+<h3 id="exists()" name="exists()">exists()</h3>
+<p>This method tests whether or not this <code>nsIFile</code> exists.</p>
+<pre class="eval">boolean exists()
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<p>None.</p>
+<h6 id="Return_value" name="Return_value">Return value</h6>
+<p><code>true</code> if the file or directory exists. Otherwise it returns <code>false</code>.</p>
+<h3 id="isDirectory()" name="isDirectory()">isDirectory()</h3>
+<p>This method tests whether or not this <code>nsIFile</code> corresponds to a directory.</p>
+<pre class="eval">boolean isDirectory();
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<p>None.</p>
+<h6 id="Return_value" name="Return_value">Return value</h6>
+<p><code>true</code> if this <code>nsIFile</code> corresponds to a directory. Otherwise it returns <code>false</code>.</p>
+<h3 id="isExecutable()" name="isExecutable()">isExecutable()</h3>
+<p>This method tests whether or not this <code>nsIFile</code> corresponds to a file that may be executed.</p>
+<div class="note style-wrap">
+ <p><strong>Note:</strong> This method does not work on all platforms due to <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=322865" title="isExecutable method of nsILocalFile reports false for executable files on OSX">bug 322865</a>.</p>
+</div>
+<pre class="eval">boolean isExecutable();
+</pre>
+<div class="note style-wrap">
+ <p><strong>Note:</strong> Use <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIProcess" title="">nsIProcess</a></code> to then execute/run this file.</p>
+</div>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<p>None.</p>
+<h6 id="Return_value" name="Return_value">Return value</h6>
+<p><code>true</code> if the <code>nsIFile</code> may be executed by the user. Otherwise it returns <code>false</code>.</p>
+<h3 id="isFile()" name="isFile()">isFile()</h3>
+<p>This method tests whether or not this <code>nsIFile</code> corresponds to a normal file.</p>
+<pre class="eval">boolean isFile();
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<p>None.</p>
+<h6 id="Return_value" name="Return_value">Return value</h6>
+<p><code>true</code> if this <code>nsIFile</code> corresponds to a normal file. Otherwise it returns <code>false</code>.</p>
+<h3 id="isHidden()" name="isHidden()">isHidden()</h3>
+<p>This method tests whether or not this <code>nsIFile</code> corresponds to a file or directory that is hidden. In Unix, hidden files start with a period. On Mac and Windows, they have an attribute bit set.</p>
+<pre class="eval">boolean isHidden();
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<p>None.</p>
+<h6 id="Return_value" name="Return_value">Return value</h6>
+<p><code>true</code> if the file or directory is hidden. Otherwise it returns <code>false</code>.</p>
+<h3 id="isReadable()" name="isReadable()">isReadable()</h3>
+<p>This method tests whether or not this <code>nsIFile</code> corresponds to a file or directory that may be read by the user.</p>
+<pre class="eval">boolean isReadable();
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<p>None.</p>
+<h6 id="Return_value" name="Return_value">Return value</h6>
+<p><code>true</code> if the file or directory may be read by the user. Otherwise it returns <code>false</code>.</p>
+<h3 id="isSpecial()" name="isSpecial()">isSpecial()</h3>
+<p>This method tests whether or not this <code>nsIFile</code> corresponds to a special system file.</p>
+<p></p><div class="blockIndicator note"><strong>Note:</strong> The definition of a special system file is platform dependent. For example, under UNIX platforms this might correspond to a device file, socket, or fifo.</div><p></p>
+<pre class="eval">boolean isSpecial();
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<p>None.</p>
+<h6 id="Return_value" name="Return_value">Return value</h6>
+<p><code>true</code> if this <code>nsIFile</code> corresponds to a special system file. Otherwise it returns <code>false</code>.</p>
+<h3 id="isSymlink()" name="isSymlink()">isSymlink()</h3>
+<p>This method tests whether or not this <code>nsIFile</code> corresponds to a symbolic link, shortcut, or alias.</p>
+<pre class="eval">boolean isSymlink();
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<p>None.</p>
+<h6 id="Return_value" name="Return_value">Return value</h6>
+<p><code>true</code> if this <code>nsIFile</code> corresponds to a symbolic link. Otherwise it returns <code>false</code>.</p>
+<h3 id="isWritable()" name="isWritable()">isWritable()</h3>
+<p>This method tests whether or not this <code>nsIFile</code> corresponds to a file or directory that may be modified by the user.  As of Gecko 9, files on read only shares will return false.  Files that are exclusively opened on Win32 will return true if they are normally writable, and files that don't have write permissions will return false. For specific handling before Gecko 9 (Firefox 9.0 / Thunderbird 9.0 / SeaMonkey 2.6), please see <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=682571" title="FIXED: nsLocalFile::isWritable behaves wrongly on Windows">bug 682571</a>.</p>
+<pre class="eval">boolean isWritable();
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<p>None.</p>
+<h6 id="Return_value" name="Return_value">Return value</h6>
+<p><code>true</code> if the file or directory may be modified by the user. Otherwise it returns <code>false</code>.</p>
+<h3 id="moveTo()" name="moveTo()">moveTo()</h3>
+<p>This method moves this file to a new location.</p>
+<div class="note">
+ <strong>Note:</strong> If this method succeeds, this instance will be updated to point to the new file.</div>
+<p>If the current file path corresponds to a regular file (for storage of bytes), and if the new leaf name identifies a regular file that already exists, then this method will overwrite the destination file.</p>
+<p>Usually, "move" means to relocate the file to a different directory without changing the file's contents or properties, or in fact the file's serial number (inode). That is a very fast operation because it just changes directory information. The actual data doesn't move.</p>
+<p>Unfortunately, an actual "move" is impossible between different volumes (disks or partitions). This method attempts to do the "right thing" when moving files across volumes. That is, it will copy the old file to the new location, try to assign the file attributes as the old file had them, and then delete the old file. You should be aware of these possible problems:</p>
+<ul>
+ <li>This process may take a long time if the file is large and/or the bandwidth is narrow.</li>
+ <li>If the <code><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFile#copyTo()">copyTo()</a></code> method loses data, such as Mac resource data, then so will such a move.</li>
+ <li>If attribute data cannot be recreated (like the file owner if you don't have enough privileges, or ACL data if moving to a non-ACL volume), then those attributes will be lost.</li>
+ <li>The new file's serial number will almost certainly be different, because it is a different file, probably stored in a different physical location.</li>
+</ul>
+<pre class="eval">void moveTo(
+ in nsIFile newParentDir,
+ in AString newName
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>newParentDir</code></dt>
+ <dd>
+ This parameter specifies the parent directory to move the file into. If this parameter is <code>null</code>, then the parent directory of the file will be used.</dd>
+ <dt>
+ <code>newName</code></dt>
+ <dd>
+ This parameter allows you to specify a new leaf name for the file to be moved. This parameter may be empty, in which case the current leaf name will be used.</dd>
+</dl>
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">Exceptions thrown</h6>
+<dl>
+ <dt>
+ <code>NS_ERROR_FILE_TARGET_DOES_NOT_EXIST</code></dt>
+ <dd>
+ Indicates that the current file path does not exist. It is not possible to move a file that does not exist.</dd>
+ <dt>
+ <code>NS_ERROR_FILE_DIR_NOT_EMPTY</code></dt>
+ <dd>
+ Indicates that an attempt was made to move a directory to the location of an existing directory that is not empty.</dd>
+ <dt>
+ <code>NS_ERROR_FILE_ACCESS_DENIED</code></dt>
+ <dd>
+ Indicates that an attempt was made to move a directory to the location of an existing directory that is not writable.</dd>
+ <dt>
+ <code>NS_ERROR_FILE_DESTINATION_NOT_DIR</code></dt>
+ <dd>
+ Indicates that "newParentDir" exists and is not a directory.</dd>
+</dl>
+<p></p><div><span class="indicatorInHeadline noscript noscriptMethod" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span><h3 id="moveToNative">moveToNative</h3></div><p></p>
+<p>This method moves this file to a new location. [native character encoding variant]</p>
+<div class="note">
+ <strong>Note:</strong> If this method succeeds, this instance will be updated to point to the new file.</div>
+<p>If the current file path corresponds to a regular file (for storage of bytes), and if the new leaf name identifies a regular file that already exists, then this method will overwrite the destination file.</p>
+<p>Usually, "move" means to relocate the file to a different directory without changing the file's contents or properties, or in fact the file's serial number (inode). That is a very fast operation because it just changes directory information. The actual data doesn't move.</p>
+<p>Unfortunately, an actual "move" is impossible between different volumes (disks or partitions). This method attempts to do the "right thing" when moving files across volumes. That is, it will copy the old file to the new location, try to assign the file attributes as the old file had them, and then delete the old file. You should be aware of these possible problems:</p>
+<ul>
+ <li>This process may take a long time if the file is large and/or the bandwidth is narrow.</li>
+ <li>If the <code><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFile#copyTo()">copyTo()</a></code> method loses data, such as Mac resource data, then so will such a move.</li>
+ <li>If attribute data cannot be recreated (like the file owner if you don't have enough privileges, or ACL data if moving to a non-ACL volume), then those attributes will be lost.</li>
+ <li>The new file's serial number will almost certainly be different, because it is a different file, probably stored in a different physical location.</li>
+</ul>
+<pre class="eval">void moveToNative(
+ in nsIFile newParentDir,
+ in ACString newName
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<p> </p>
+<dl>
+ <dt>
+ <code>newParentDir</code></dt>
+ <dd>
+ This parameter specifies the parent directory to copy the file into. If this parameter is <code>null</code>, then the parent directory of the file will be used.</dd>
+ <dt>
+ <code>newName</code></dt>
+ <dd>
+ This parameter allows you to specify a new leaf name for the file to be copied. This parameter may be empty, in which case the current leaf name will be used. This string must be encoded using the native character encoding.</dd>
+</dl>
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">Exceptions thrown</h6>
+<dl>
+ <dt>
+ <code>NS_ERROR_FILE_TARGET_DOES_NOT_EXIST</code></dt>
+ <dd>
+ Indicates that the current file path does not exist. It is not possible to move a file that does not exist.</dd>
+ <dt>
+ <code>NS_ERROR_FILE_DIR_NOT_EMPTY</code></dt>
+ <dd>
+ Indicates that an attempt was made to move a directory to the location of an existing directory that is not empty.</dd>
+ <dt>
+ <code>NS_ERROR_FILE_ACCESS_DENIED</code></dt>
+ <dd>
+ Indicates that an attempt was made to move a directory to the location of an existing directory that is not writable.</dd>
+ <dt>
+ <code>NS_ERROR_FILE_DESTINATION_NOT_DIR</code></dt>
+ <dd>
+ Indicates that "newParentDir" exists and is not a directory.</dd>
+</dl>
+<h3 id="normalize()" name="normalize()">normalize()</h3>
+<p>This method is used to canonicalize the path represented by this <code>nsIFile</code>. (for example removing .. and . components on Unix).</p>
+<p>As of <span title="">Gecko 1.7</span>, this method is only implemented under UNIX builds (except for Mac OSX). This method will fail if the path does not exist.</p>
+<pre class="eval">void normalize();
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<p>None.</p>
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">Exceptions thrown</h6>
+<dl>
+ <dt>
+ <code>NS_ERROR_FILE_TARGET_DOES_NOT_EXIST</code></dt>
+ <dd>
+ Indicates that the file path does not exist.</dd>
+ <dt>
+ <code>NS_ERROR_FILE_DESTINATION_NOT_DIR</code></dt>
+ <dd>
+ Indicates that a component of the path prefix is not a directory.</dd>
+ <dt>
+ <code>NS_ERROR_FILE_ACCESS_DENIED</code></dt>
+ <dd>
+ Read or search permission was denied for a component of the path prefix.</dd>
+</dl>
+<h3 id="remove()" name="remove()">remove()</h3>
+<p>This method removes the file or directory corresponding to the file path represented by this <code>nsIFile</code>.</p>
+<p>This method will not resolve any symlinks.</p>
+<pre class="eval">void remove(
+ in boolean recursive
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>recursive</code></dt>
+ <dd>
+ If this <code>nsIFile</code> corresponds to a directory that is not empty, then this parameter must be <code>true</code> in order for the directory to be deleted. Otherwise, this parameter is ignored.</dd>
+</dl>
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">Exceptions thrown</h6>
+<dl>
+ <dt>
+ <code>NS_ERROR_FILE_TARGET_DOES_NOT_EXIST</code></dt>
+ <dd>
+ Indicates that the current file path does not exist. It is not possible to remove a file that does not exist.</dd>
+ <dt>
+ <code>NS_ERROR_FILE_DIR_NOT_EMPTY</code></dt>
+ <dd>
+ Indicates that an attempt was made to remove a directory that is not empty.</dd>
+ <dt>
+ <code>NS_ERROR_FILE_ACCESS_DENIED</code></dt>
+ <dd>
+ Indicates that an attempt was made to remove a file in a way that exceeded your permissions. Details depend on your file system and how its permissions work.</dd>
+</dl>
+<h2 id="Remarks" name="Remarks">Remarks</h2>
+<p>All string-valued methods and attributes have two forms. The preferred form operates on UTF-16 (Unicode) encoded character strings. The alternate form operates on character strings encoded in the "native" multibyte character set. The native character encoding is defined as the single-byte character encoding used with the standard fopen function on the host system.</p>
+<p>The native character encoding is determined using platform specific methods. As of <span title="">Gecko 1.7</span>, it is UTF-8 on Mac OS X. On Linux and other UNIX platforms, it is the value returned from nl_langinfo (CODESET), which usually corresponds to the value of the LC_ALL, LC_CTYPE and LANG environment variables (with the precedence the same as the order they're enumerated). On Win32 platforms, it is the currently selected ANSI codepage (specified by CP_ACP).</p>
+<p>The word "Native" appears in the name of methods that operate on or return strings encoded in the native character set.</p>
+<p>A string containing characters encoded in the native character set cannot be safely passed to JavaScript via XPConnect. Therefore, the "native" methods and attributes are not scriptable.</p>
+<p>XPCOM provides the string conversion functions <a href="/en/NS_CStringToUTF16" title="en/NS_CStringToUTF16">NS_CStringToUTF16</a> and <a href="/en/NS_UTF16ToCString" title="en/NS_UTF16ToCString">NS_UTF16ToCString</a>, which can be used to convert a string between UTF-16 and the native character encoding.</p>
+<p>This interface was frozen for <span title="">Gecko 1.0</span>. See <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=129279" title="FIXED: nsIFile unicode/utf8/ascii task">bug 129279</a> for details. From <span title="(Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1)">Gecko 2.0</span> interfaces are no longer frozen.</p>
+<h2 id="See_also" name="See_also">See also</h2>
+<ul>
+ <li><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsILocalFile" title="">nsILocalFile</a></code></li>
+ <li><a href="/en/NS_CStringToUTF16" title="en/NS_CStringToUTF16">NS_CStringToUTF16</a></li>
+ <li><a href="/en/NS_UTF16ToCString" title="en/NS_UTF16ToCString">NS_UTF16ToCString</a></li>
+</ul>
+<p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsifilepicker/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsifilepicker/index.html
new file mode 100644
index 0000000000..7122dcd1ef
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsifilepicker/index.html
@@ -0,0 +1,376 @@
+---
+title: nsIFilePicker
+slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIFilePicker
+tags:
+ - Filepicker
+ - 文件选取器
+translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIFilePicker
+---
+<p></p><div style="border: solid #ddd 2px; margin-bottom: 12px;">
+<div style="background: #eee; padding: 2px;"><code><a href="https://dxr.mozilla.org/mozilla-central/source/widget/nsIFilePicker.idl" rel="custom">widget/nsIFilePicker.idl</a></code><span style="text-align: right; float: right;"><a href="/zh-CN/docs/Interfaces/About_Scriptable_Interfaces" style="color: #00cc00; font-weight: 700;">脚本化</a></span></div>
+<span style="padding: 4px 2px;">
+
+文件选择器组件是通过显示标准的用户界面来让用户来选择文件和目录,以及选择目的地来命名和新建文件。
+</span>
+
+<div style="background: #eee; padding: 2px;">
+继承于: <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupports" title="">nsISupports</a></code>
+<span style="text-align: right; float: right;">最后修改于Gecko 17.0 (Firefox 17.0 / Thunderbird 17.0 / SeaMonkey 2.14)</span></div>
+</div><p></p>
+
+<p>实现自: <code>@mozilla.org/filepicker;1</code>。要创建一个实例,使用以下代码:</p>
+
+<pre class="eval">var filePicker = Components.classes["@mozilla.org/filepicker;1"]
+ .createInstance(Components.interfaces.nsIFilePicker);
+</pre>
+
+<h2 id="Method_overview" name="Method_overview">方法概述</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>void <a href="#appendFilter()">appendFilter</a>(in AString title, in AString filter);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#appendFilters()">appendFilters</a>(in long filterMask);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#init()">init</a>(in nsIDOMWindow parent, in AString title, in short mode);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#open()">open</a>(in nsIFilePickerShownCallback aFilePickerShownCallback);</code> </td>
+ </tr>
+ <tr>
+ <td><code>short <a href="#show()">show</a>();</code> <span class="inlineIndicator deprecated deprecatedInline" title="(Firefox 17.0 / Thunderbird 17.0 / SeaMonkey 2.14)">已废弃 Gecko 17.0</span></td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Attributes" name="Attributes">属性</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">属性</td>
+ <td class="header">类型</td>
+ <td class="header">说明</td>
+ </tr>
+ <tr>
+ <td><code>addToRecentDocs</code> </td>
+ <td><code>boolean</code></td>
+ <td>If <code>true</code>, the file is added to the operating system's "recent documents" list (if the operating system has one; nothing happens if there is no such concept on the user's platform). This attribute has no effect if private browsing mode is in effect.</td>
+ </tr>
+ <tr>
+ <td><code>defaultExtension</code></td>
+ <td><code><a href="/en/AString" title="en/AString">AString</a></code></td>
+ <td>The extension for the type of files you want to work with. On some platforms, this is automatically appended to filenames the user enters, if required.  Specify it without a leading dot, for example "jpg".</td>
+ </tr>
+ <tr>
+ <td><code>defaultString</code></td>
+ <td><code><a href="/en/AString" title="en/AString">AString</a></code></td>
+ <td>The filename, including extension, that should be suggested to the user as a default. This should be set this before calling <code><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFilePicker#open()">open()</a></code> or <code><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFilePicker#show()">show()</a></code>.
+ <h6 id="Exceptions_thrown" name="Exceptions_thrown">Exceptions thrown</h6>
+
+ <dl>
+ <dt><code>NS_ERROR_FAILURE</code></dt>
+ <dd>If you try to read this attribute.</dd>
+ </dl>
+ </td>
+ </tr>
+ <tr>
+ <td><code>displayDirectory</code></td>
+ <td><code><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsILocalFile" title="">nsILocalFile</a></code></code></td>
+ <td>The directory that the file picker dialog should initially display. This should be set this before calling <code><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFilePicker#open()">open()</a></code> or <code><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFilePicker#show()">show()</a></code> to specify a starting point.</td>
+ </tr>
+ <tr>
+ <td><code>file</code></td>
+ <td><code><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsILocalFile" title="">nsILocalFile</a></code></code></td>
+ <td>The currently selected file or directory. <strong>Read only.</strong></td>
+ </tr>
+ <tr>
+ <td><code>files</code></td>
+ <td><code><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISimpleEnumerator" title="">nsISimpleEnumerator</a></code></code></td>
+ <td>
+ <p>An enumerator of the currently selected files. <strong>Read only.</strong></p>
+ <div class="blockIndicator note"><strong>Note:</strong> Only works with <code>modeOpenMultiple</code> mode.</div></td>
+ </tr>
+ <tr>
+ <td><code>fileURL</code></td>
+ <td><code><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIURI" title="">nsIURI</a></code></code></td>
+ <td>The URI of the currently selected file or directory. <strong>Read only.</strong></td>
+ </tr>
+ <tr>
+ <td><code>filterIndex</code></td>
+ <td><code><a href="/en/long" title="en/long">long</a></code></td>
+ <td>The (0-based) index of the filter which is currently selected in the file picker dialog. Set this to choose a particular filter to be selected by default.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Constants" name="Constants">常量</h2>
+
+<h3 id="Mode_constants" name="Mode_constants">模式常量</h3>
+
+<p>These constants are used to specify the type of file picker to create when calling <code><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFilePicker#init()">init()</a></code>.</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">常量</td>
+ <td class="header">值</td>
+ <td class="header">说明</td>
+ </tr>
+ <tr>
+ <td><code>modeOpen</code></td>
+ <td><code>0</code></td>
+ <td>Load a file or directory.</td>
+ </tr>
+ <tr>
+ <td><code>modeSave</code></td>
+ <td><code>1</code></td>
+ <td>Save a file or directory.</td>
+ </tr>
+ <tr>
+ <td><code>modeGetFolder</code></td>
+ <td><code>2</code></td>
+ <td>Select a folder/directory.</td>
+ </tr>
+ <tr>
+ <td><code>modeOpenMultiple</code></td>
+ <td><code>3</code></td>
+ <td>Load multiple files.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Return_value_constants" name="Return_value_constants">返回值常量</h3>
+
+<p>These values are returned by <code><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFilePicker#show()">show()</a></code>, indicating the result of the file picker activity.</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">Constant</td>
+ <td class="header">Value</td>
+ <td class="header">Description</td>
+ </tr>
+ <tr>
+ <td><code>returnOK</code></td>
+ <td><code>0</code></td>
+ <td>The file picker dialog was closed by the user hitting 'Ok'</td>
+ </tr>
+ <tr>
+ <td><code>returnCancel</code></td>
+ <td><code>1</code></td>
+ <td>The file picker dialog was closed by the user hitting 'Cancel'</td>
+ </tr>
+ <tr>
+ <td><code>returnReplace</code></td>
+ <td><code>2</code></td>
+ <td>The user chose an existing file and acknowledged that they want to overwrite the file</td>
+ </tr>
+ </tbody>
+</table>
+
+<h3 id="Filter_constants" name="Filter_constants">筛选器常量</h3>
+
+<p>These constants are used to create filters for commonly-used file types. For the most up to date list see <a href="https://dxr.mozilla.org/mozilla-central/source/toolkit/content/filepicker.properties" rel="custom">filepicker.properties</a>.</p>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">Constant</td>
+ <td class="header">Value</td>
+ <td class="header">Description</td>
+ </tr>
+ <tr>
+ <td><code>filterAll</code></td>
+ <td><code>0x001</code></td>
+ <td>Corresponds to the *.* filter for file extensions. All files will pass through the filter.</td>
+ </tr>
+ <tr>
+ <td><code>filterHTML</code></td>
+ <td><code>0x002</code></td>
+ <td>Corresponds to the *.html, *.htm, *.shtml and *.xhtml filters for file extensions.</td>
+ </tr>
+ <tr>
+ <td><code>filterText</code></td>
+ <td><code>0x004</code></td>
+ <td>Corresponds to the *.txt and *.text filter for file extensions.</td>
+ </tr>
+ <tr>
+ <td><code>filterImages</code></td>
+ <td><code>0x008</code></td>
+ <td>Corresponds to the *.jpe, *.jpg, *.jpeg, *.gif, *.png, *.bmp, *.ico, *.svg, *.svgz, *.tif, *.tiff, *.ai, *.drw, *.pct, *.psp, *.xcf, *.psd and *.raw filters for file extensions.</td>
+ </tr>
+ <tr>
+ <td><code>filterXML</code></td>
+ <td><code>0x010</code></td>
+ <td>Corresponds to the *.xml filter for file extensions.</td>
+ </tr>
+ <tr>
+ <td><code>filterXUL</code></td>
+ <td><code>0x020</code></td>
+ <td>Corresponds to the *.xul filter for file extensions.</td>
+ </tr>
+ <tr>
+ <td><code>filterApps</code></td>
+ <td><code>0x040</code></td>
+ <td>Corresponds to the platform specific application filter for file extensions. Application files for the user's platform will pass through the filter.</td>
+ </tr>
+ <tr>
+ <td><code>filterAllowURLs</code></td>
+ <td><code>0x80</code></td>
+ <td>Allow URLs. </td>
+ </tr>
+ <tr>
+ <td><code>filterAudio</code></td>
+ <td><code>0x100</code></td>
+ <td>Corresponds to the *.aac, *.aif, *.flac, *.iff, *.m4a, *.m4b, *.mid, *.midi, *.mp3, *.mpa, *.mpc, *.oga, *.ogg, *.ra, *.ram, *.snd, *.wav and *.wma filters for file extensions. </td>
+ </tr>
+ <tr>
+ <td><code>filterVideo</code></td>
+ <td><code>0x200</code></td>
+ <td>Corresponds to the *.avi, *.divx, *.flv, *.m4v, *.mkv, *.mov, *.mp4, *.mpeg, *.mpg, *.ogm, *.ogv, *.ogx, *.rm, *.rmvb, *.smil, *.webm, *.wmv and *.xvid filters for file extensions. </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Methods" name="Methods">方法</h2>
+
+<h3 id="appendFilter()" name="appendFilter()">appendFilter()</h3>
+
+<p>Appends a custom file extension filter to the dialog. The filter appended first will be used to display the <code>nsIFilePicker</code> dialog, the user may then select another from the list.</p>
+
+<pre class="eval">void appendFilter(
+ in AString title,
+ in AString filter
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<dl>
+ <dt><code>title</code></dt>
+ <dd>The title of the filter.</dd>
+ <dt><code>filter</code></dt>
+ <dd>The filter string. Multiple extensions may be included, separated by a semicolon and a space.</dd>
+</dl>
+
+<h6 id="appendFilter_example" name="appendFilter_example">Example</h6>
+
+<p>Some example filter strings:</p>
+
+<ul>
+ <li>"*.ics"</li>
+ <li>"*.txt; *.doc; *.rtf"</li>
+</ul>
+
+<h3 id="appendFilters()" name="appendFilters()">appendFilters()</h3>
+
+<p>Appends a list of file extension filters, from the predefined list, to the dialog.</p>
+
+<pre class="eval">void appendFilters(
+ in long filterMask
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<div class="note"><strong>Note:</strong> If <code>appendFilters</code> is the first (or only) call to set the file filters the filter with the smallest code will be used as default filter when displaying the <code>nsIFilePicker</code> dialog. If you would like to use another you must append it separately before the others you want to go into the drop down list.</div>
+
+<dl>
+ <dt><code>filterMask</code></dt>
+ <dd>A combination of the <a class="internal" href="#Filter_constants" title="Filter constants">filters</a> you wish to use. You may OR multiple filters together; for example <code>filterAll | filterHTML</code>.</dd>
+</dl>
+
+<h3 id="init()" name="init()">init()</h3>
+
+<p>Initialize the file picker widget. The file picker is not valid until this method is called.</p>
+
+<pre class="eval">void init(
+ in nsIDOMWindow parent,
+ in AString title,
+ in short mode
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<dl>
+ <dt><code>parent</code></dt>
+ <dd>The <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMWindow" title="">nsIDOMWindow</a></code> parent. This dialog will be dependent on this parent. Must be non-null.</dd>
+ <dt><code>title</code></dt>
+ <dd>The file picker dialog title. If this is <code>null</code>, the dialog will have the default title.</dd>
+ <dt><code>mode</code></dt>
+ <dd>One of the <a class="internal" href="#Mode_constants" title="Mode constants">mode constants</a>, indicating the type of picker to create.</dd>
+</dl>
+
+<h3 id="open">open</h3>
+
+<p>Opens the file dialog asynchrounously. The passed in object's done method will be called upon completion.</p>
+
+<pre class="eval">void open(
+ in nsIFilePickerShownCallback aFilePickerShownCallback
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<dl>
+ <dt><code>aFilePickerShownCallback</code></dt>
+ <dd>The <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFilePickerShownCallback" title="">nsIFilePickerShownCallback</a></code> to be called on completion.</dd>
+</dl>
+
+<h3 id="show">show</h3>
+
+<p>Displays the file picker dialog. The dialog is displayed modally.</p>
+
+<pre class="eval">short show();
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<p>None.</p>
+
+<h6 id="Return_value" name="Return_value">Return value</h6>
+
+<p>One of the <a class="internal" href="#Return_value_constants" title="Return value constants">return constants</a>.</p>
+
+<h2 id="Example" name="Example">示例</h2>
+
+<p>Here's an example:</p>
+
+<pre>const nsIFilePicker = Components.interfaces.nsIFilePicker;
+
+var fp = Components.classes["@mozilla.org/filepicker;1"]
+ .createInstance(nsIFilePicker);
+fp.init(window, "Dialog Title", nsIFilePicker.modeOpen);
+fp.appendFilters(nsIFilePicker.filterAll | nsIFilePicker.filterText);
+
+var rv = fp.show();
+if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
+ var file = fp.file;
+ // Get the path as string. Note that you usually won't
+ // need to work with the string paths.
+ var path = fp.file.path;
+ // work with returned nsILocalFile...
+}
+</pre>
+
+<p>If your code is a component and <code>window</code> is not defined, you can get one using <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIWindowMediator" title="">nsIWindowMediator</a></code>.</p>
+
+<p>When selecting multiple files:</p>
+
+<pre> ....
+ fp.init(window, "Dialog Title", nsIFilePicker.modeOpenMultiple);
+ ....
+
+ var files = fp.files;
+ var paths = [];
+ while (files.hasMoreElements())
+ {
+ var arg = files.getNext().QueryInterface(Components.interfaces.nsILocalFile).path;
+ paths.push(arg);
+ }
+</pre>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsihttpchannel/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsihttpchannel/index.html
new file mode 100644
index 0000000000..b469773f43
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsihttpchannel/index.html
@@ -0,0 +1,365 @@
+---
+title: nsIHttpChannel
+slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIHttpChannel
+translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIHttpChannel
+---
+<p></p><div style="border: solid #ddd 2px; margin-bottom: 12px;">
+<div style="background: #eee; padding: 2px;"><code><a href="https://dxr.mozilla.org/mozilla-central/source/netwerk/protocol/http/nsIHttpChannel.idl" rel="custom">netwerk/protocol/http/nsIHttpChannel.idl</a></code><span style="text-align: right; float: right;"><a href="/zh-CN/docs/Interfaces/About_Scriptable_Interfaces" style="color: #00cc00; font-weight: 700;">脚本化</a></span></div>
+<span style="padding: 4px 2px;">
+
+This interface allows for the modification of HTTP request parameters and the inspection of the resulting HTTP response status and headers when they become available.
+</span>
+
+<div style="background: #eee; padding: 2px;">
+继承于: <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIChannel" title="">nsIChannel</a></code>
+<span style="text-align: right; float: right;">最后修改于Gecko 1.3 </span></div>
+</div><p></p>
+
+<p>To create an HTTP channel, use <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIIOService" title="">nsIIOService</a></code> with a HTTP URI, for example:</p>
+
+<pre class="eval">var ios = Components.classes["@mozilla.org/network/io-service;1"]
+ .getService(Components.interfaces.nsIIOService);
+var ch = ios.newChannel("<a class="linkification-ext external" href="http://www.example.com/" title="Linkification: http://www.example.com/">http://www.example.com/</a>", null, null);
+</pre>
+
+<h2 id="Method_overview" name="Method_overview">方法概述</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>ACString <a href="#getRequestHeader()">getRequestHeader</a>(in ACString aHeader);</code></td>
+ </tr>
+ <tr>
+ <td><code>ACString <a href="#getResponseHeader()">getResponseHeader</a>(in ACString header);</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#isNoCacheResponse()">isNoCacheResponse</a>();</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#isNoStoreResponse()">isNoStoreResponse</a>();</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#setRequestHeader()">setRequestHeader</a>(in ACString aHeader, in ACString aValue, in boolean aMerge);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#setResponseHeader()">setResponseHeader</a>(in ACString header, in ACString value, in boolean merge);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#visitRequestHeaders()">visitRequestHeaders</a>(in nsIHttpHeaderVisitor aVisitor);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#visitResponseHeaders()">visitResponseHeaders</a>(in nsIHttpHeaderVisitor aVisitor);</code></td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Attributes" name="Attributes">属性</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">属性名</td>
+ <td class="header">类型</td>
+ <td class="header">描述</td>
+ </tr>
+ <tr>
+ <td><code>allowPipelining</code></td>
+ <td><code><a href="/zh-CN/boolean" title="zh-CN/boolean">boolean</a></code></td>
+ <td>
+ <p>This attribute is a hint to the channel to indicate whether or not the underlying HTTP transaction should be allowed to be pipelined with other transactions. This should be set to <code>false</code>, for example, if the application knows that the corresponding document is likely to be very large.</p>
+
+ <p>This attribute is <code>true</code> by default, though other factors may prevent pipelining.</p>
+ This attribute may only be set before the channel is opened.
+
+ <h6 id="Exceptions_thrown" name="Exceptions_thrown">可能抛出的异常</h6>
+
+ <dl>
+ <dt><code>NS_ERROR_FAILURE</code></dt>
+ <dd>If set after the channel has been opened.</dd>
+ </dl>
+ </td>
+ </tr>
+ <tr>
+ <td><code>redirectionLimit</code></td>
+ <td><code><a href="/zh-CN/unsigned_long" title="zh-CN/unsigned long">unsigned long</a></code></td>
+ <td>
+ <p>This attribute specifies the number of redirects this channel is allowed to make. If zero, the channel will fail to redirect and will generate a <code>NS_ERROR_REDIRECT_LOOP</code> failure status.</p>
+ <div class="blockIndicator note"><strong>Note:</strong> An HTTP redirect results in a new channel being created. If the new channel supports <code>nsIHttpChannel</code>, then it will be assigned a value to its <code>redirectionLimit</code> attribute one less than the value of the redirected channel's <code>redirectionLimit</code> attribute. The initial value for this attribute may be a configurable preference (depending on the implementation).</div></td>
+ </tr>
+ <tr>
+ <td><code>referrer</code></td>
+ <td><code><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIURI" title="">nsIURI</a></code></code></td>
+ <td>
+ <p>Get or set the URI of the HTTP <code>Referer:</code> header. This is the address (URI) of the resource from which this channel's URI was obtained (see RFC2616 section 14.36).</p>
+
+ <p>This attribute may only be set before the channel is opened.</p>
+ <div class="blockIndicator note"><strong>Note:</strong> The channel may silently refuse to set the Referer: header if the URI does not pass certain security checks (e.g., a "https://" URL will never be sent as the <code>referrer</code> for a plaintext HTTP request). The implementation is not required to throw an exception when the <code>referrer</code> URI is rejected.</div>
+
+ <h6 id="Exceptions_thrown" name="Exceptions_thrown">可能抛出的异常</h6>
+
+ <dl>
+ <dt><code>NS_ERROR_IN_PROGRESS</code></dt>
+ <dd>If set after the channel has been opened.</dd>
+ </dl>
+ </td>
+ </tr>
+ <tr>
+ <td><code>requestMethod</code></td>
+ <td><code><a href="/zh-CN/ACString" title="zh-CN/ACString">ACString</a></code></td>
+ <td>
+ <p>获取或设置HTTP请求方法(默认为"GET").设置时不区分大小写,获取时返回的都是大写字母组成的字符串.</p>
+
+ <p>该属性的值只能在通道打开之前进行设置.</p>
+
+ <p></p><div class="blockIndicator note"><strong>Note:</strong>  The data for a "POST" or "PUT" request can be configured via <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIUploadChannel" title="">nsIUploadChannel</a></code>. However, after setting the upload data, it may be necessary to set the request method explicitly. The documentation for <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIUploadChannel" title="">nsIUploadChannel</a></code> has further details. </div><p></p>
+
+ <h6 id="Exceptions_thrown" name="Exceptions_thrown">可能抛出的异常</h6>
+
+ <dl>
+ <dt><code>NS_ERROR_IN_PROGRESS</code></dt>
+ <dd>If set after the channel has been opened.</dd>
+ </dl>
+ </td>
+ </tr>
+ <tr>
+ <td><code>requestSucceeded</code></td>
+ <td><code><a href="/zh-CN/boolean" title="zh-CN/boolean">boolean</a></code></td>
+ <td>
+ <p>Returns <code>true</code> if the HTTP response code indicates success. The value of <code><a href="https://developer.mozilla.org/zh-CN/docs/XPCOM_Interface_Reference/nsIRequest#status()">nsIRequest.status()</a></code> will be NS_OK even when processing a <code><a href="/zh-CN/HTTP/HTTP_response_codes#404" title="https://developer.mozilla.org/zh-CN/HTTP/HTTP_response_codes#404">404 File Not Found</a></code> response because such a response may include a message body that (in some cases) should be shown to the user. Use this attribute to distinguish server error pages from normal pages, instead of comparing the response status manually against the set of valid response codes, if that is required by your application. <strong>Read only.</strong></p>
+
+ <h6 id="Exceptions_thrown" name="Exceptions_thrown">可能抛出的异常</h6>
+
+ <dl>
+ <dt><code>NS_ERROR_NOT_AVAILABLE</code></dt>
+ <dd>If called before the response has been received (before <code>onStartRequest()</code>).</dd>
+ </dl>
+ </td>
+ </tr>
+ <tr>
+ <td><code>responseStatus</code></td>
+ <td><code><a href="/zh-CN/unsigned_long" title="zh-CN/unsigned long">unsigned long</a></code></td>
+ <td>获取HTTP响应状态码(比如200). <strong>只读.</strong>
+ <h6 id="Exceptions_thrown" name="Exceptions_thrown">可能抛出的异常</h6>
+
+ <dl>
+ <dt><code>NS_ERROR_NOT_AVAILABLE</code></dt>
+ <dd>If called before the response has been received (before <code>onStartRequest()</code>).</dd>
+ </dl>
+ </td>
+ </tr>
+ <tr>
+ <td><code>responseStatusText</code></td>
+ <td><code><a href="/zh-CN/ACString" title="zh-CN/ACString">ACString</a></code></td>
+ <td>
+ <p>获取HTTP响应状态信息(比如"OK").</p>
+ <div class="blockIndicator note"><strong>Note:</strong> This returns the raw (possibly 8-bit) text from the server. There are no assumptions made about the charset of the returned text. You have been warned!</div> <strong>Read only.</strong>
+
+ <h6 id="Exceptions_thrown" name="Exceptions_thrown">可能抛出的异常</h6>
+
+ <dl>
+ <dt><code>NS_ERROR_NOT_AVAILABLE</code></dt>
+ <dd>If called before the response has been received (before <code>onStartRequest()</code>).</dd>
+ </dl>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Methods" name="Methods">方法</h2>
+
+<h3 id="getRequestHeader()" name="getRequestHeader()">getRequestHeader()</h3>
+
+<p>Get the value of a particular request header.</p>
+
+<pre class="eval">ACString getRequestHeader(
+ in ACString aHeader
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">参数</h6>
+
+<dl>
+ <dt><code>aHeader</code></dt>
+ <dd>需要查询的请求头名称,不区分大小写(比如"Cache-Control").</dd>
+</dl>
+
+<h6 id="Return_value" name="Return_value">返回值</h6>
+
+<p>指定请求头的值.</p>
+
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">可能抛出的异常</h6>
+
+<dl>
+ <dt><code>NS_ERROR_NOT_AVAILABLE</code></dt>
+ <dd>如果没有这个请求头</dd>
+</dl>
+
+<h3 id="getResponseHeader()" name="getResponseHeader()">getResponseHeader()</h3>
+
+<p>获取指定响应头的值.</p>
+
+<pre class="eval">ACString getResponseHeader(
+ in ACString header
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">参数</h6>
+
+<dl>
+ <dt><code>header</code></dt>
+ <dd>需要查询的响应头名称,不区分大小写(比如"Set-Cookie").</dd>
+</dl>
+
+<h6 id="Return_value" name="Return_value">返回值</h6>
+
+<p>指定响应头的值.</p>
+
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">可能抛出的异常</h6>
+
+<dl>
+ <dt><code>NS_ERROR_NOT_AVAILABLE</code></dt>
+ <dd>在响应头还未完全返回的时候调用了该方法(before <code>onStartRequest()</code>),或者响应中没有包含此响应头的情况下.</dd>
+</dl>
+
+<h3 id="isNoCacheResponse()" name="isNoCacheResponse()">isNoCacheResponse()</h3>
+
+<p>Returns <code>true</code> if the server sent the equivalent of a "Cache-Control: no-cache" response header. Equivalent response headers include: "Pragma: no-cache", "Expires: 0", and "Expires" with a date value in the past relative to the value of the "Date" header.</p>
+
+<pre class="eval">boolean isNoCacheResponse();
+</pre>
+
+<h6 id="Parameters" name="Parameters">参数</h6>
+
+<p>无</p>
+
+<h6 id="Return_value" name="Return_value">返回值</h6>
+
+<p>如果服务器返回了"Cache-control: no-cache"或者其他能够禁止缓存的响应头,则<code>该方法返回true</code>,否则返回<code>false</code>.</p>
+
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">可能抛出的异常</h6>
+
+<dl>
+ <dt><code>NS_ERROR_NOT_AVAILABLE</code></dt>
+ <dd>在响应头还未完全返回的时候调用了该方法(before <code>onStartRequest()</code>).</dd>
+</dl>
+
+<h3 id="isNoStoreResponse()" name="isNoStoreResponse()">isNoStoreResponse()</h3>
+
+<pre class="eval">boolean isNoStoreResponse();
+</pre>
+
+<h6 id="Parameters" name="Parameters">参数</h6>
+
+<p>无</p>
+
+<h6 id="Return_value" name="Return_value">返回值</h6>
+
+<p>如果服务器返回了"Cache-Control: no-store"这样的响应头,则<code>该方法返回true</code>,否则返回<code>false</code>.</p>
+
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">可能抛出的异常</h6>
+
+<dl>
+ <dt><code>NS_ERROR_NOT_AVAILABLE</code></dt>
+ <dd>在响应头还未完全返回的时候调用了该方法(before <code>onStartRequest()</code>).</dd>
+</dl>
+
+<h3 id="setRequestHeader()" name="setRequestHeader()">setRequestHeader()</h3>
+
+<p>This method is called to set the value of a particular request header. This method allows, for example, the cookies module to add "Cookie" headers to the outgoing HTTP request. This method may only be called before the channel is opened. If aValue is empty and aMerge is <code>false</code>, the header will be cleared.</p>
+
+<pre class="eval">void setRequestHeader(
+ in ACString aHeader,
+ in ACString aValue,
+ in boolean aMerge
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">参数</h6>
+
+<dl>
+ <dt><code>aHeader</code></dt>
+ <dd>指定请求头的名称,不区分大小写(例如"Cookie").</dd>
+ <dt><code>aValue</code></dt>
+ <dd>指定请求头的值(例如"X=1").</dd>
+ <dt><code>aMerge</code></dt>
+ <dd>如果该参数为<code>true</code>,则新指定的请求头的值会合并到该请求头已有的值的后面.如果指定的请求头不支持(或者说不适合)新旧值的合并操作,则这个参数会被忽略(比如"<span>Connection</span>"头就只能有一个值).具体那些请求头会忽略掉这个参数,本文档不会给出.如果该参数的值为<code>false</code>,则新指定的请求头的值会覆盖掉该请求头已有的值.</dd>
+</dl>
+
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">可能抛出的异常</h6>
+
+<dl>
+ <dt><code>NS_ERROR_IN_PROGRESS</code></dt>
+ <dd>在通道已经打开之后才调用了该方法</dd>
+</dl>
+
+<h3 id="setResponseHeader()" name="setResponseHeader()">setResponseHeader()</h3>
+
+<p>设置指定响应头的值.This method allows, for example, the HTML content sink to inform the HTTP channel about HTTP-EQUIV headers found in HTML &lt;META&gt; tags. If value is empty and merge is <code>false</code>, the header will be cleared.</p>
+
+<pre class="eval">void setResponseHeader(
+ in ACString header,
+ in ACString value,
+ in boolean merge
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">参数</h6>
+
+<dl>
+ <dt><code>header</code></dt>
+ <dd>指定响应头的名称,不区分大小写(例如"Cache-Control").</dd>
+ <dt><code>value</code></dt>
+ <dd>指定响应头的值(例如"no-cache").</dd>
+ <dt><code>merge</code></dt>
+ <dd>如果该参数为<code>true</code>,则新指定的响应头的值会合并到该响应头已有的值的后面.如果指定的响应头不支持(或者说不适合)新旧值的合并操作,则这个参数会被忽略(比如"Content-Type"头就只能有一个值).具体那些响应头会忽略掉这个参数,本文档不会给出.如果该参数的值为<code>false</code>,则新指定的响应头的值会覆盖掉该响应头已有的值.</dd>
+</dl>
+
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">可能抛出的异常</h6>
+
+<dl>
+ <dt><code>NS_ERROR_NOT_AVAILABLE</code></dt>
+ <dd>在响应头还未完全返回的时候调用了该方法(before <code>onStartRequest()</code>).</dd>
+ <dt><code>NS_ERROR_ILLEGAL_VALUE</code></dt>
+ <dd>If changing the value of this response header is not allowed.</dd>
+</dl>
+
+<h3 id="visitRequestHeaders()" name="visitRequestHeaders()">visitRequestHeaders()</h3>
+
+<p>Call this method to visit all request headers. Calling <code><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIHttpChannel#setRequestHeader()">setRequestHeader()</a></code> while visiting request headers has undefined behavior. Don't do it!</p>
+
+<pre class="eval">void visitRequestHeaders(
+ in nsIHttpHeaderVisitor aVisitor
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">参数</h6>
+
+<dl>
+ <dt><code>aVisitor</code></dt>
+ <dd>The header visitor instance.</dd>
+</dl>
+
+<h3 id="visitResponseHeaders()" name="visitResponseHeaders()">visitResponseHeaders()</h3>
+
+<p>Call this method to visit all response headers.</p>
+
+<p>{</p><div class="warning"> Calling <code><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIHttpChannel#setResponseHeader()">setResponseHeader()</a></code> while visiting response headers has undefined behavior. Don't do it! </div><p></p>
+
+<pre class="eval">void visitResponseHeaders(
+ in nsIHttpHeaderVisitor aVisitor
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">参数</h6>
+
+<dl>
+ <dt><code>aVisitor</code></dt>
+ <dd>The header visitor instance.</dd>
+</dl>
+
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">可能抛出的异常</h6>
+
+<dl>
+ <dt><code>NS_ERROR_NOT_AVAILABLE</code></dt>
+ <dd>If called before the response has been received (before <code>onStartRequest()</code>).</dd>
+</dl>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiidleservice/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiidleservice/index.html
new file mode 100644
index 0000000000..a0dec4ad73
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiidleservice/index.html
@@ -0,0 +1,119 @@
+---
+title: nsIIdleService
+slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIIdleService
+translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIIdleService
+---
+<p><span class="lang lang-en"><code>nsIIdleService </code>的定义文档是:<span class="lang lang-en"><a class="external" href="http://mxr.mozilla.org/mozilla-central/source/widget/public/nsIIdleService.idl" rel="external nofollow" title="http://mxr.mozilla.org/mozilla-central/source/widget/public/nsIIdleService.idl"><code>widget/public/nsIIdleService.idl</code></a> </span>。 It is <span class="lang lang-en"><a href="../../../../en/Interfaces/About_Scriptable_Interfaces" rel="internal">scriptable</a> </span> and <span class="lang lang-en"> <a href="../../../../en/Interfaces/About_Frozen_Interfaces" rel="internal">unfrozen</a> (hasn't changed since Mozilla 1.9a) </span>. </span></p>
+<h2 id="Summary" name="Summary">概要</h2>
+<p>该服务可使您监测到空闲时间,例如,用户没有进行鼠标或者键盘等操作。您可直接捕获到空闲的时间,但一般,需要注册一个监听。</p>
+<p>目前<code> nsIIdleService</code> 服务在 Windows, Mac OS X, and Linux (via XScreenSaver) 等系统上都已实现。</p>
+<p>实现: <code>@mozilla.org/widget/idleservice;1</code>。创建实例如:</p>
+<pre class="eval">var idleService = Components.classes["@mozilla.org/widget/idleservice;1"]
+ .getService(Components.interfaces.nsIIdleService)
+</pre>
+<h2 id="Method_overview" name="Method_overview">方法预览</h2>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>void <a href="#addIdleObserver.28.29">addIdleObserver</a>(in <a href="/en/nsIObserver" title="en/nsIObserver">nsIObserver</a> observer, in unsigned long time)</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#removeIdleObserver.28.29">removeIdleObserver</a>(in <a href="/en/nsIObserver" title="en/nsIObserver">nsIObserver</a> observer, in unsigned long time)</code></td>
+ </tr>
+ </tbody>
+</table>
+<h2 id="Attributes" name="Attributes">属性</h2>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">属性</td>
+ <td class="header">类型</td>
+ <td class="header">描述</td>
+ </tr>
+ <tr>
+ <td><code>idleTime</code></td>
+ <td><code>long</code></td>
+ <td>The amount of time in milliseconds that has passed since the last user activity. <em>Read only.</em></td>
+ </tr>
+ </tbody>
+</table>
+<h2 id="Methods" name="Methods">方法</h2>
+<h3 id="addIdleObserver.28.29" name="addIdleObserver.28.29">addIdleObserver()</h3>
+<p>添加一个observer,用于侦听使用者何时离开,及何时归来。</p>
+<pre class="eval">void addIdleObserver(
+ in nsIObserver observer,
+ in unsigned long time
+)
+</pre>
+<h6 id="Parameters" name="Parameters">参数 </h6>
+<dl>
+ <dt>
+ <code>observer</code></dt>
+ <dd>
+ The <a href="/en/nsIObserver" title="en/nsIObserver">observer</a> to be notified.</dd>
+</dl>
+<dl>
+ <dt>
+ <code>time</code></dt>
+ <dd>
+    使用者离开多少秒钟后,开始侦听。</dd>
+</dl>
+<h6 id="Remarks" name="Remarks">备注</h6>
+<ul>
+ <li>observer 侦听的 subject 一直是 nsIIdleSerivce 。当空闲时, observer 的 topic 是 'idle' , 当他回来时,将为 'back' 。侦听的参数中包含当前使用空闲的时间。</li>
+</ul>
+<ul>
+ <li>相同的 observer 可以添加两次。</li>
+</ul>
+<ul>
+ <li>大多数实现需要自己在 OS 中查询 idle 信息,侦听可能会出现延迟,这取决于在实现中查询的间隔时间的长度。当前实现中使用的是 5 秒钟的延迟时间。</li>
+</ul>
+<p></p><div class="blockIndicator geckoMinVer standardNote">
+ <div style="text-align: center; font-weight: bold; padding-bottom: 0.5em;">Gecko 1.9.2 note</div>
+ <div>从版本 Gecko 1.9.2 开始,增加一个新的侦听消息:‘idle-daily’ 。</div>
+</div><p></p>
+<h3 id="removeIdleObserver.28.29" name="removeIdleObserver.28.29">removeIdleObserver()</h3>
+<p>删除observer。</p>
+<pre class="eval">void removeIdleObserver(
+ in nsIObserver observer,
+ in unsigned long time
+)
+</pre>
+<h6 id="Parameters_2" name="Parameters_2">参数</h6>
+<dl>
+ <dt>
+ <code>observer</code></dt>
+ <dd>
+ the <a href="/en/nsIObserver" title="en/nsIObserver">observer</a> to be removed</dd>
+</dl>
+<dl>
+ <dt>
+ <code>time</code></dt>
+ <dd>
+ 消息侦听的时间(一段时间)。</dd>
+</dl>
+<p>备注</p>
+<p>删除 observer 时,根据指定的 idle 时间来删除。如果已经添加了多个 observer ,则需要删除多次。</p>
+<h2 id="Example_Code" name="Example_Code">示例:</h2>
+<p>例一:</p>
+<pre class="eval">var idleService = Components.classes["@mozilla.org/widget/idleservice;1"]
+ .getService(Components.interfaces.nsIIdleService)
+setTimeout(function() { alert(idleService.idleTime) }, 1000)
+// if you don't use the mouse or the keyboard after running this snippet,
+// you'll see a number around 1000 alerted.
+</pre>
+<p>例二:</p>
+<pre class="eval">var idleService = Components.classes["@mozilla.org/widget/idleservice;1"]
+ .getService(Components.interfaces.nsIIdleService)
+var idleObserver = {
+ observe: function(subject, topic, data) {
+ alert("topic: " + topic + "\ndata: " + data);
+ }
+};
+idleService.addIdleObserver(idleObserver, 60); // one minute
+// ...
+// Don't forget to remove the observer using removeIdleObserver!
+idleService.removeIdleObserver(idleObserver, 60);
+</pre>
+<p><span class="comment">Interwiki Language Links</span></p>
+<p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsilocalfile/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsilocalfile/index.html
new file mode 100644
index 0000000000..882450bf87
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsilocalfile/index.html
@@ -0,0 +1,478 @@
+---
+title: nsILocalFile
+slug: Mozilla/Tech/XPCOM/Reference/Interface/nsILocalFile
+translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsILocalFile
+---
+<p> </p>
+
+<div class="note">
+<p>In <span title="(Firefox 14 / Thunderbird 14 / SeaMonkey 2.11)">Gecko 14</span> this Interface was merged into the <code><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFile" title="">nsIFile</a></code> interface.</p>
+</div>
+
+<p> </p>
+
+<p></p><div style="border: solid #ddd 2px; margin-bottom: 12px;">
+<div style="background: #eee; padding: 2px;"><code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/io/nsILocalFile.idl" rel="custom">xpcom/io/nsILocalFile.idl</a></code><span style="text-align: right; float: right;"><a href="/zh-CN/docs/Interfaces/About_Scriptable_Interfaces" style="color: #00cc00; font-weight: 700;">脚本化</a></span></div>
+<span style="padding: 4px 2px;">
+
+This interface adds methods to <code>nsIFile</code> that are particular to a file that is accessible via the local file system.
+</span>
+
+ <div style="height: 42px; position: relative; padding: 2px; width: auto;">
+
+ <div style="top: 22px; font-size: 11px; position: absolute; left: 0px; text-align: right; float: right; width: 100%;">66</div>
+
+<div style="height: 8px; top: 16px; left: 0%; background: #00dd00; position: absolute; width: 25.71428571428571%;" title="Introduced in Gecko 1.0 "></div>
+
+<div style="top: 0px; font-size: 11px; position: absolute; left: 0%;">Introduced</div>
+<div style="top: 22px; font-size: 11px; position: absolute; left: 0%;">Gecko 1.0</div>
+
+ <div style="height: 8px; top: 16px; left: 25.71428571428571%; background: #ff8000; position: absolute; width: 74.28571428571429%;" title="Deprecated in Gecko 14 (Firefox 14 / Thunderbird 14 / SeaMonkey 2.11)"></div>
+
+ <div style="top: 0px; font-size: 11px; position: absolute; left: 25.71428571428571%;">Deprecated</div>
+ <div style="top: 22px; font-size: 11px; position: absolute; left: 25.71428571428571%;">Gecko 14</div>
+
+</div>
+
+<div style="background: #eee; padding: 2px;">
+继承于: <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFile" title="">nsIFile</a></code>
+<span style="text-align: right; float: right;">最后修改于Gecko 1.0 </span></div>
+</div><p></p>
+
+<p>Implemented by: <code>@mozilla.org/file/local;1</code>. To create an instance, use:</p>
+
+<pre class="eval">var localFile = Components.classes["@mozilla.org/file/local;1"]
+ .createInstance(Components.interfaces.nsILocalFile);
+</pre>
+
+<h2 id="Method_overview" name="Method_overview">Method overview</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>void <a href="#appendRelativeNativePath()">appendRelativeNativePath</a>(in ACString relativeFilePath);</code> <span class="inlineIndicator noscript noscriptInline" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#appendRelativePath()">appendRelativePath</a>(in AString relativeFilePath);</code></td>
+ </tr>
+ <tr>
+ <td><code>ACString <a href="#getRelativeDescriptor()">getRelativeDescriptor</a>(in nsILocalFile fromFile);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#initWithFile()">initWithFile</a>(in nsILocalFile aFile);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#initWithNativePath()">initWithNativePath</a>(in ACString filePath);</code> <span class="inlineIndicator noscript noscriptInline" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#initWithPath()">initWithPath</a>(in AString filePath);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#launch()">launch</a>();</code></td>
+ </tr>
+ <tr>
+ <td><code>PRLibraryStar <a href="#load()">load</a>();</code> <span class="inlineIndicator noscript noscriptInline" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span></td>
+ </tr>
+ <tr>
+ <td><code>FILE <a href="#openANSIFileDesc()">openANSIFileDesc</a>(in string mode);</code> <span class="inlineIndicator noscript noscriptInline" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span></td>
+ </tr>
+ <tr>
+ <td><code>PRFileDescStar <a href="#openNSPRFileDesc()">openNSPRFileDesc</a>(in long flags, in long mode);</code> <span class="inlineIndicator noscript noscriptInline" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#reveal()">reveal</a>();</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#setRelativeDescriptor()">setRelativeDescriptor</a>(in nsILocalFile fromFile, in ACString relativeDesc);</code></td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Attributes" name="Attributes">Attributes</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">Attribute</td>
+ <td class="header">Type</td>
+ <td class="header">Description</td>
+ </tr>
+ <tr>
+ <td><code>diskSpaceAvailable</code></td>
+ <td><code><a href="/zh-cn/PRInt64" title="zh-cn/PRInt64">PRInt64</a></code></td>
+ <td>The number of bytes available to non-superuser on the disk volume containing the <code>nsILocalFile</code>. <strong>Read only.</strong></td>
+ </tr>
+ <tr>
+ <td><code>followLinks</code></td>
+ <td><code><a href="/zh-cn/PRBool" title="zh-cn/PRBool">PRBool</a></code></td>
+ <td>
+ <p>Determines whether or not the <code>nsILocalFile</code> will automatically resolve symbolic links.</p>
+ By default, this value is <code>false</code> on all non-UNIX systems. As of Mozilla 1.7, this attribute is ignored on UNIX systems.</td>
+ </tr>
+ <tr>
+ <td><code>persistentDescriptor</code></td>
+ <td><code><a href="/zh-cn/ACString" title="zh-cn/ACString">ACString</a></code></td>
+ <td>
+ <p>On some platforms, the value of <a href="https://developer.mozilla.org/zh-CN/docs/XPCOM_Interface_Reference/nsIFile#path">nsIFile.path</a> may be insufficient to uniquely identify the file on the local file system. The persistent descriptor is intended to be used whenever a <code>nsILocalFile</code> needs to be serialized to disk and later recovered. This string is not intended for display to users.</p>
+ <div class="blockIndicator note"><strong>Note:</strong> The value of the <code>followLinks</code> attribute is not encoded in the persistent descriptor.</div></td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Constants" name="Constants">Constants</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">Constant</td>
+ <td class="header">Value</td>
+ <td class="header">Description</td>
+ </tr>
+ <tr>
+ <td><code>DELETE_ON_CLOSE</code></td>
+ <td><code>0x80000000</code></td>
+ <td>Optional parameter used by <code><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsILocalFile#openNSPRFileDesc()">openNSPRFileDesc()</a></code>. </td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Methods" name="Methods">Methods</h2>
+
+<p></p><div><span class="indicatorInHeadline noscript noscriptMethod" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span><h3 id="appendRelativeNativePath">appendRelativeNativePath</h3></div><p></p>
+
+<p>Appends a relative, native character encoding, path to the current path of the <code>nsILocalFile</code> object.</p>
+
+<pre class="eval">void appendRelativeNativePath(
+ in ACString relativeFilePath
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<dl>
+ <dt><code>relativeFilePath</code></dt>
+ <dd>A native relative path. For security reasons, this cannot contain '..' or cannot start with a directory separator '.'. Must be in the native file system character set.</dd>
+</dl>
+
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">Exceptions thrown</h6>
+
+<dl>
+ <dt><code>NS_ERROR_FILE_UNRECOGNIZED_PATH</code></dt>
+ <dd>Indicates that <code>relativeFilePath</code> incorrectly begins with a path separator character or otherwise contains invalid characters.</dd>
+</dl>
+
+<h3 id="appendRelativePath()" name="appendRelativePath()">appendRelativePath()</h3>
+
+<p>Appends a relative native path to the current path of the <code>nsILocalFile</code> object.</p>
+
+<pre class="eval">void appendRelativePath(
+ in AString relativeFilePath
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<dl>
+ <dt><code>relativeFilePath</code></dt>
+ <dd>A native relative path. For security reasons, this cannot contain '..' or cannot start with a directory separator '.' .</dd>
+</dl>
+
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">Exceptions thrown</h6>
+
+<dl>
+ <dt><code>NS_ERROR_FILE_UNRECOGNIZED_PATH</code></dt>
+ <dd>Indicates that <code>relativeFilePath</code> incorrectly begins with a path separator character or otherwise contains invalid characters.</dd>
+</dl>
+
+<h3 id="getRelativeDescriptor()" name="getRelativeDescriptor()">getRelativeDescriptor()</h3>
+
+<p>Returns a relative file path in an opaque, cross platform format. It is therefore not a native path.</p>
+
+<pre class="eval">ACString getRelativeDescriptor(
+ in nsILocalFile fromFile
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<dl>
+ <dt><code>fromFile</code></dt>
+ <dd>The file from which the descriptor is relative. There is no defined result if this parameter is <code>null</code>.</dd>
+</dl>
+
+<h6 id="Return_value" name="Return_value">Return value</h6>
+
+<p>An opaque string value with undefined character encoding. This string is not intended for display to users.</p>
+
+<p>The result returned from this method may be used with <code><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsILocalFile#setRelativeDescriptor()">setRelativeDescriptor()</a></code> to initialize a <code>nsILocalFile</code> instance.</p>
+
+<h3 id="initWithFile()" name="initWithFile()">initWithFile()</h3>
+
+<p>Initializes this object with another file.</p>
+
+<pre class="eval">void initWithFile(
+ in nsILocalFile aFile
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<dl>
+ <dt><code>aFile</code></dt>
+ <dd>The file this becomes equivalent to.</dd>
+</dl>
+
+<p></p><div><span class="indicatorInHeadline noscript noscriptMethod" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span><h3 id="initWithNativePath">initWithNativePath</h3></div><p></p>
+
+<p>Used to set the full path that this <code>nsILocalFile</code> references. All current settings will be reset.</p>
+
+<pre class="eval">void initWithNativePath(
+ in ACString filePath
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<dl>
+ <dt><code>filePath</code></dt>
+ <dd>A string that specifies a platform-specific, full path to a file or directory. Must be in the native file system character set.</dd>
+</dl>
+
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">Exceptions thrown</h6>
+
+<dl>
+ <dt><code>NS_ERROR_FILE_UNRECOGNIZED_PATH</code></dt>
+ <dd>Indicates that FilePath is not an absolute file path.</dd>
+</dl>
+
+<h3 id="initWithPath()" name="initWithPath()">initWithPath()</h3>
+
+<p>Used to set the full path that this <code>nsILocalFile</code> references. All current settings will be reset.</p>
+
+<pre class="eval">void initWithPath(
+ in AString filePath
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<dl>
+ <dt><code>filePath</code></dt>
+ <dd>A string that specifies a platform-specific, full path to a file or directory.</dd>
+</dl>
+
+<h6 id="Exceptions_thrown" name="Exceptions_thrown">Exceptions thrown</h6>
+
+<dl>
+ <dt><code>NS_ERROR_FILE_UNRECOGNIZED_PATH</code></dt>
+ <dd>Indicates that FilePath is not an absolute file path.</dd>
+</dl>
+
+<h3 id="launch()" name="launch()">launch()</h3>
+
+<p>Requests that the operating system attempt to open this file.</p>
+
+<pre class="eval">void launch();
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<p>None.</p>
+
+<p></p><div><span class="indicatorInHeadline noscript noscriptMethod" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span><h3 id="load">load</h3></div><p></p>
+
+<p>Returns the result of <a href="/zh-cn/PR_LoadLibrary" title="zh-cn/PR LoadLibrary"><code>PR_LoadLibrary()</code></a> on the file. The caller is responsible for calling <a href="/zh-cn/PR_UnloadLibrary" title="zh-cn/PR UnloadLibrary"><code>PR_UnloadLibrary()</code></a> on the result.</p>
+
+<pre class="eval">PRLibraryStar load();
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<p>None.</p>
+
+<h6 id="Return_value" name="Return_value">Return value</h6>
+
+<p>A pointer to a <a href="/zh-cn/PRLibrary" title="zh-cn/PRLibrary"><code>PRLibrary</code></a>.</p>
+
+<h6 id="Example" name="Example">Example</h6>
+
+<pre class="brush: cpp">#include "prlink.h"
+#include "nsError.h"
+#include "nsILocalFile.h"
+
+// Load the DLL corresponding to the given nsILocalFile...
+
+nsresult LoadDLL(nsILocalFile *aLocalFile)
+{
+ PRLibrary *dll;
+ nsresult rv = aLocalFile-&gt;Load(&amp;dll);
+ if (NS_FAILED(rv))
+ return rv;
+
+ // Do something with the library now that it is open...
+
+ PR_FreeLibrary(dll);
+ return NS_OK;
+}
+</pre>
+
+<p></p><div><span class="indicatorInHeadline noscript noscriptMethod" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span><h3 id="openANSIFileDesc">openANSIFileDesc</h3></div><p></p>
+
+<p>Returns the result of <code>fopen()</code> on the file. The caller is responsible for calling <code>fclose()</code> on the result.</p>
+
+<pre class="eval">FILE openANSIFileDesc(
+ in string mode
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<dl>
+ <dt><code>mode</code></dt>
+ <dd>An ANSI file open mode string, which will be passed to <code>fopen()</code>.</dd>
+</dl>
+
+<h6 id="Return_value" name="Return_value">Return value</h6>
+
+<p>A pointer to an ANSI <code>FILE</code> type.</p>
+
+<h6 id="Example" name="Example">Example</h6>
+
+<pre class="brush: cpp">#include &lt;stdio.h&gt;
+#include "nsError.h"
+#include "nsILocalFile.h"
+
+// Read the contents of a nsILocalFile...
+
+nsresult ReadLocalFile(nsILocalFile *aLocalFile)
+{
+ FILE *fp;
+ nsresult rv = aLocalFile-&gt;OpenANSIFileDesc("r", &amp;fp);
+ if (NS_FAILED(rv))
+ return rv;
+
+ char buf[512];
+ size_t n;
+
+ while ((n = fread(buf, sizeof(buf), 1, fp)) &gt; 0)
+ {
+ // Do something with n-byte block of data from file...
+ }
+
+ if (ferror(fp) != 0)
+ rv = NS_ERROR_UNEXPECTED;
+
+ fclose(fp);
+ return rv;
+}
+</pre>
+
+<p></p><div><span class="indicatorInHeadline noscript noscriptMethod" title="This method may only be called from C++; don't use it from JavaScript.">Native code only!</span><h3 id="openNSPRFileDesc">openNSPRFileDesc</h3></div><p></p>
+
+<p>Returns the result of <a href="/zh-cn/PR_Open" title="zh-cn/PR Open"><code>PR_Open()</code></a> on the file. The caller is responsible for calling <a href="/zh-cn/PR_Close" title="zh-cn/PR Close"><code>PR_Close()</code></a> on the result.</p>
+
+<pre class="eval">PRFileDescStar openNSPRFileDesc(
+ in long flags,
+ in long mode
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<dl>
+ <dt><code>flags</code></dt>
+ <dd>
+ <p>The <a href="/zh-cn/PR_Open" title="zh-cn/PR Open"><code>PR_Open()</code></a> flags from <code><a href="https://dxr.mozilla.org/mozilla-central/source/nsprpub/pr/include/prio.h" rel="custom">nsprpub/pr/include/prio.h</a></code>, plus optionally <code>DELETE_ON_CLOSE</code>. <code>DELETE_ON_CLOSE</code> may be implemented by removing the file (by path name) immediately after opening it, so beware of possible races; the file should be exclusively owned by this process.</p>
+
+ <p>A bitwise combination of the following open flags:</p>
+
+ <ul>
+ <li><code><strong>PR_RDONLY</strong></code> Open for reading only.</li>
+ <li><code><strong>PR_WRONLY</strong></code> Open for writing only.</li>
+ <li><code><strong>PR_RDWR</strong></code> Open for reading and writing.</li>
+ <li><code><strong>PR_CREATE_FILE</strong></code> If the file does not exist, the file is created. If the file exists, this flag has no effect.</li>
+ <li><code><strong>PR_APPEND</strong></code> The file pointer is set to the end of the file prior to each write.</li>
+ <li><code><strong>PR_TRUNCATE</strong></code> If the file exists, its length is truncated to 0.</li>
+ <li><code><strong>PR_SYNC</strong></code> If set, each write will wait for both the file data and file status to be physically updated.</li>
+ <li><code><strong>PR_EXCL</strong></code> With <code>PR_CREATE_FILE</code>, if the file does not exist, the file is created. If the file already exists, no action and null is returned.</li>
+ <li><code><strong>DELETE_ON_CLOSE</strong></code> File will be deleted when closed.</li>
+ </ul>
+ </dd>
+ <dt><code>mode</code></dt>
+ <dd>A UNIX-style file permissions value. For example, the octal value 0600 may be used to limit read and write access to the current user of the system. This parameter may be ignored on systems that do not support file permissions.</dd>
+</dl>
+
+<h6 id="Return_value" name="Return_value">Return value</h6>
+
+<p>If the file is successfully opened, returns a pointer to the <a href="/zh-cn/PRFileDesc" title="zh-cn/PRFileDesc"><code>PRFileDesc</code></a> created for the newly opened file. Returns a null pointer if the open failed.</p>
+
+<h6 id="Example" name="Example">Example</h6>
+
+<pre class="brush: cpp">#include "prio.h"
+#include "nsError.h"
+#include "nsILocalFile.h"
+
+// Read the contents of a nsILocalFile...
+
+nsresult ReadLocalFile(nsILocalFile *aLocalFile)
+{
+ PRFileDesc *fd;
+ nsresult rv = aLocalFile-&gt;OpenNSPRFileDesc(PR_RDONLY, 0, &amp;fd);
+ if (NS_FAILED(rv))
+ return rv;
+
+ char buf[512];
+ PRInt32 n;
+
+ while ((n = PR_Read(fd, buf, sizeof(buf))) &gt; 0)
+ {
+ // Do something with n-byte block of data from file...
+ }
+
+ if (n &lt; 0)
+ rv = NS_ERROR_UNEXPECTED;
+
+ PR_Close(fd);
+ return rv;
+}
+</pre>
+
+<h3 id="reveal()" name="reveal()">reveal()</h3>
+
+<p>Ask the operating system to open the folder which contains this file or folder. This routine only works on platforms which support the ability to open a folder. See the note in the <a href="#Remarks">remarks</a> below.</p>
+
+<pre class="eval">void reveal();
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<p>None.</p>
+
+<h3 id="setRelativeDescriptor()" name="setRelativeDescriptor()">setRelativeDescriptor()</h3>
+
+<p>Initializes the file to the location relative to <code>fromFile</code> using a string returned by <code><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsILocalFile#getRelativeDescriptor()">getRelativeDescriptor()</a></code>.</p>
+
+<pre class="eval">void setRelativeDescriptor(
+ in nsILocalFile fromFile,
+ in ACString relativeDesc
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<dl>
+ <dt><code>fromFile</code></dt>
+ <dd>The file to which the descriptor is relative.</dd>
+ <dt><code>relativeDesc</code></dt>
+ <dd>The relative descriptor obtained from <code><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsILocalFile#getRelativeDescriptor()">getRelativeDescriptor()</a></code>.</dd>
+</dl>
+
+<h2 id="Remarks" name="Remarks">Remarks</h2>
+
+<p>The methods <code><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsILocalFile#initWithNativePath()">initWithNativePath()</a></code> and <code><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsILocalFile#appendRelativeNativePath()">appendRelativeNativePath()</a></code> take string valued parameters that are encoded using the native character encoding. That means, you cannot deal with files whose name contain characters outside the default code page on Windows even though Windows 2000 or later has no problem with them. Therefore, <strong>never</strong> use these functions unless you are absolutely sure that the path passed to them is <strong>always</strong> ASCII-only. See <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFile" title="">nsIFile</a></code> for more information on the native character encoding.</p>
+
+<h2 id="See_also" name="See_also">See also</h2>
+
+<ul>
+ <li><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFile" title="">nsIFile</a></code></li>
+</ul>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiprocess/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiprocess/index.html
new file mode 100644
index 0000000000..1abc109440
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiprocess/index.html
@@ -0,0 +1,283 @@
+---
+title: nsIProcess
+slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIProcess
+translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIProcess
+---
+<p></p><div style="border: solid #ddd 2px; margin-bottom: 12px;">
+<div style="background: #eee; padding: 2px;"><code><a href="https://dxr.mozilla.org/mozilla-central/source/xpcom/threads/nsIProcess.idl" rel="custom">xpcom/threads/nsIProcess.idl</a></code><span style="text-align: right; float: right;"><a href="/zh-CN/docs/Interfaces/About_Scriptable_Interfaces" style="color: #00cc00; font-weight: 700;">脚本化</a></span></div>
+<span style="padding: 4px 2px;">
+
+This interface represents an executable process.
+</span>
+
+<div style="background: #eee; padding: 2px;">
+继承于: <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupports" title="">nsISupports</a></code>
+<span style="text-align: right; float: right;">最后修改于Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1)</span></div>
+</div><p></p>
+<p>Implemented by: <code>@mozilla.org/process/util;1</code>. To create an instance, use:</p>
+<pre class="eval">var process = Components.classes["@mozilla.org/process/util;1"]
+ .createInstance(Components.interfaces.nsIProcess);
+</pre>
+<h2 id="Method_overview" name="Method_overview">Method overview</h2>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>void <a href="#init()">init</a>(in nsIFile executable);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#initWithPid()">initWithPid</a>(in unsigned long pid);</code> <span class="inlineIndicator obsolete obsoleteInline" title="(Firefox 3.6 / Thunderbird 3.1 / Fennec 1.0)">已废弃 Gecko 1.9.2</span></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#kill()">kill</a>();</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#run()">run</a>(in boolean blocking, [array, size_is(count)] in string args, in unsigned long count);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#runAsync()">runAsync</a>([array, size_is(count)] in string args, in unsigned long count, [optional] in nsIObserver observer, [optional] in boolean holdWeak);</code> </td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#runw()">runw</a>(in boolean blocking, [array, size_is(count)] in wstring args, in unsigned long count);</code> </td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#runwAsync()">runwAsync</a>([array, size_is(count)] in wstring args, in unsigned long count, [optional] in nsIObserver observer, [optional] in boolean holdWeak);</code> </td>
+ </tr>
+ </tbody>
+</table>
+<h2 id="Attributes" name="Attributes">属性</h2>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">属性名称</td>
+ <td class="header">属性类型</td>
+ <td class="header">属性描述</td>
+ </tr>
+ <tr>
+ <td><code>exitValue</code></td>
+ <td><code><a href="/zh-cn/long" title="zh-cn/long">long</a></code></td>
+ <td>The value returned by the process upon exit. This is only valid after the process has exited. <strong>Read only.</strong></td>
+ </tr>
+ <tr>
+ <td><code>isRunning</code></td>
+ <td><code><a href="/zh-cn/boolean" title="zh-cn/boolean">boolean</a></code></td>
+ <td><code>true</code> if the process is running, otherwise <code>false</code>. Only accurate if the process was run with blocking disabled. <strong>Read only.</strong> </td>
+ </tr>
+ <tr>
+ <td><code>location</code></td>
+ <td><code><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFile" title="">nsIFile</a></code></code></td>
+ <td>
+ <p>The location of the executable file on disk. <strong>Read only.</strong></p>
+ <p></p><div class="blockIndicator geckoMinVer standardNote">
+ <div style="text-align: center; font-weight: bold; padding-bottom: 0.5em;">Gecko 1.9.1 note</div>
+ <div>This attribute is no longer implemented as of Gecko 1.9.1, and is removed entirely in Gecko 1.9.2.</div>
+</div><p></p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>pid</code></td>
+ <td><code><a href="/zh-cn/unsigned_long" title="zh-cn/unsigned long">unsigned long</a></code></td>
+ <td>The process ID of the process. This value is only available after the process has started; in addition, some platforms may not offer this value at all. <strong>Read only.</strong></td>
+ </tr>
+ <tr>
+ <td><code>processName</code></td>
+ <td><code><a href="/zh-cn/string" title="zh-cn/string">string</a></code></td>
+ <td>
+ <p>The name of the process. <strong>Read only.</strong></p>
+ <p></p><div class="blockIndicator geckoMinVer standardNote">
+ <div style="text-align: center; font-weight: bold; padding-bottom: 0.5em;">Gecko 1.9.1 note</div>
+ <div>This attribute is no longer implemented as of Gecko 1.9.1, and is removed entirely in Gecko 1.9.2.</div>
+</div><p></p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>processSignature</code></td>
+ <td><code><a href="/zh-cn/unsigned_long" title="zh-cn/unsigned long">unsigned long</a></code></td>
+ <td>
+ <p>The process signature. <strong>Read only.</strong></p>
+ <p></p><div class="blockIndicator geckoMinVer standardNote">
+ <div style="text-align: center; font-weight: bold; padding-bottom: 0.5em;">Gecko 1.9.1 note</div>
+ <div>This attribute is no longer implemented as of Gecko 1.9.1, and is removed entirely in Gecko 1.9.2.</div>
+</div><p></p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<h2 id="Methods" name="Methods">方法</h2>
+<h3 id="init()" name="init()">init()</h3>
+<p>Initializes the <code>nsIProcess</code> with the specified executable file. Once initialized, you can start the process executing by calling <code><a href="https://developer.mozilla.org/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIProcess#run()">run()</a></code>.</p>
+<p></p><div class="blockIndicator note"><strong>Note:</strong> This function does not work with application bundles on Mac OS X, see <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=307463" title="nsProcess::init fails for Mac OS X application bundles (foo.app)">bug 307463</a> for details.</div><p></p>
+<pre class="eval">void init(
+ in nsIFile executable
+);
+</pre>
+<h6 id="Parameters" name="Parameters">参数</h6>
+<dl>
+ <dt>
+ <code>executable</code></dt>
+ <dd>
+ The <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFile" title="">nsIFile</a></code> executable file to be represented by the <code>nsIProcess</code> object.</dd>
+</dl>
+<p></p><div class="headingWithIndicator">
+ <h3 id="initWithPid()">initWithPid()</h3>
+ <span class="indicatorInHeadline obsolete obsoleteMethod">已废弃 Gecko 1.9.2 (Firefox 3.6 / Thunderbird 3.1 / Fennec 1.0)</span>
+ </div><p></p>
+<p>Initializes the <code>nsIProcess</code> to represent an existing process, given that process's ID.</p>
+<p></p><div class="blockIndicator geckoMinVer standardNote">
+ <div style="text-align: center; font-weight: bold; padding-bottom: 0.5em;">Gecko 1.9.1 note</div>
+ <div>This method is no longer implemented as of Gecko 1.9.1, and is removed entirely in Gecko 1.9.2.</div>
+</div><p></p>
+<pre class="eval">void initWithPid(
+ in unsigned long pid
+);
+</pre>
+<h6 id="Parameters" name="Parameters">参数</h6>
+<dl>
+ <dt>
+ <code>pid</code></dt>
+ <dd>
+ The process ID to begin to represent.</dd>
+</dl>
+<h3 id="kill()" name="kill()">kill()</h3>
+<p>立即终止该<code>nsIProcess对象所代表的进程</code>,只在该进程是非阻塞方式启动的情况下才有效.</p>
+<p></p><div class="blockIndicator geckoMinVer standardNote">
+ <div style="text-align: center; font-weight: bold; padding-bottom: 0.5em;">Gecko 1.9.1 note</div>
+ <div>在Gecko 1.9.1 (Firefox 3.5)之前版本中, 该方法在Windows和Mac OS X下无效.目前此bug已经修复.</div>
+</div><p></p>
+<pre class="eval">void kill();
+</pre>
+<h6 id="Parameters" name="Parameters">参数</h6>
+<p>无.</p>
+<h3 id="run()" name="run()">run()</h3>
+<p>开始执行进程.</p>
+<p></p><div class="blockIndicator geckoMinVer standardNote">
+ <div style="text-align: center; font-weight: bold; padding-bottom: 0.5em;">Gecko 1.9.1 note</div>
+ <div>在Gecko 1.9.1 (Firefox 3.5)之前版本中,该方法会返回一个新执行进程的进程ID,目前已经不会返回任何值.</div>
+</div><p></p>
+<pre class="eval">void run(
+ in boolean blocking,
+ [array, size_is(count)] in string args,
+ in unsigned long count
+);
+</pre>
+<h6 id="Parameters" name="Parameters">参数</h6>
+<dl>
+ <dt>
+ <code>blocking</code></dt>
+ <dd>
+ 如果为<code>true</code>,则该方法会阻塞,直到所打开的进程关闭为止,如果为<code>false</code>,则该方法会立即返回.</dd>
+ <dt>
+ <code>args</code></dt>
+ <dd>
+ An array of <code>count</code> arguments, using the native character set, to be passed to the executable on its command line.</dd>
+ <dt>
+ <code>count</code></dt>
+ <dd>
+ 参数<code>args中的参数个数</code>.</dd>
+</dl>
+<p></p><h3 id="runAsync()">runAsync()</h3><p></p>
+<p>Asynchronously runs the process with which the object was initialized, optionally calling an observer when the process finishes running.</p>
+<pre class="eval">void runAsync(
+ [array, size_is(count)] in string args,
+ in unsigned long count,
+ in nsIObserver observer, <span class="inlineIndicator optional optionalInline">可选</span>
+ in boolean holdWeak <span class="inlineIndicator optional optionalInline">可选</span>
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>args</code></dt>
+ <dd>
+ An array of arguments to pass into the process, using the native character set. This array must have <code>count</code> entries.</dd>
+ <dt>
+ <code>count</code></dt>
+ <dd>
+ The number of arguments passed in the <code>args</code> array.</dd>
+ <dt>
+ <code>observer</code> <span class="inlineIndicator optional optionalInline">可选</span></dt>
+ <dd>
+ An observer that will be notified when the process exits. The observer will receive this <code>nsIProcess</code> instance as the subject and "process-finished" or "process-failed" as the topic. The observer will be notified on the main thread.</dd>
+ <dt>
+ <code>holdWeak</code> <span class="inlineIndicator optional optionalInline">可选</span></dt>
+ <dd>
+ If <code>true</code>, a <a class="internal" href="/zh-cn/Weak_reference" title="zh-cn/Weak reference">weak reference</a> is used to hold the observer.</dd>
+ <dd>
+  </dd>
+</dl>
+<p></p><h3 id="runw()">runw()</h3><p></p>
+<p>Executes the file this object was initialized with.</p>
+<pre class="eval">void runw(
+ in boolean blocking,
+ [array, size_is(count)] in wstring args,
+ in unsigned long count
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>blocking</code></dt>
+ <dd>
+ If <code>true</code>, this method will block until the process terminates; if <code>false</code>, the method returns immediately.</dd>
+ <dt>
+ <code>args</code></dt>
+ <dd>
+ An array of <code>count</code> arguments, using UTF-16, to be passed to the executable on its command line.</dd>
+ <dt>
+ <code>count</code></dt>
+ <dd>
+ The number of arguments in the <code>args</code> array.</dd>
+</dl>
+<p></p><h3 id="runwAsync()">runwAsync()</h3><p></p>
+<p>Asynchronously runs the process with which the object was initialized, optionally calling an observer when the process finishes running.</p>
+<pre class="eval">void runwAsync(
+ [array, size_is(count)] in wstring args,
+ in unsigned long count,
+ in nsIObserver observer, <span class="inlineIndicator optional optionalInline">可选</span>
+ in boolean holdWeak <span class="inlineIndicator optional optionalInline">可选</span>
+);
+</pre>
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>args</code></dt>
+ <dd>
+ An array of arguments to pass into the process, using UTF-16. This array must have <code>count</code> entries.</dd>
+ <dt>
+ <code>count</code></dt>
+ <dd>
+ The number of arguments passed in the <code>args</code> array.</dd>
+ <dt>
+ <code>observer</code> <span class="inlineIndicator optional optionalInline">可选</span></dt>
+ <dd>
+ An observer that will be notified when the process exits. The observer will receive this <code>nsIProcess</code> instance as the subject and "process-finished" or "process-failed" as the topic. The observer will be notified on the main thread.</dd>
+ <dt>
+ <code>holdWeak</code> <span class="inlineIndicator optional optionalInline">可选</span></dt>
+ <dd>
+ If <code>true</code>, a <a class="internal" href="/zh-cn/Weak_reference" title="zh-cn/Weak reference">weak reference</a> is used to hold the observer.</dd>
+</dl>
+<h2 id="See_also" name="See_also">Example</h2>
+<pre class="brush: js">// create an nsILocalFile for the executable
+var file = Components.classes["@mozilla.org/file/local;1"]
+ .createInstance(Components.interfaces.nsILocalFile);
+file.initWithPath("c:\\myapp.exe");
+
+// create an nsIProcess
+var process = Components.classes["@mozilla.org/process/util;1"]
+ .createInstance(Components.interfaces.nsIProcess);
+process.init(file);
+
+// Run the process.
+// If first param is true, calling thread will be blocked until
+// called process terminates.
+// Second and third params are used to pass command-line arguments
+// to the process.
+var args = ["argument1", "argument2"];
+process.run(false, args, args.length);
+</pre>
+<h2 id="See_also" name="See_also">See also</h2>
+<ul>
+ <li><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFile" title="">nsIFile</a></code></li>
+ <li><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsILocalFile" title="">nsILocalFile</a></code></li>
+ <li><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIProcess2" title="">nsIProcess2</a></code> <span class="inlineIndicator obsolete obsoleteInline" title="(Firefox 3.6 / Thunderbird 3.1 / Fennec 1.0)">已废弃 Gecko 1.9.2</span></li>
+</ul>
+<p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiprompt/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiprompt/index.html
new file mode 100644
index 0000000000..9bd2106964
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiprompt/index.html
@@ -0,0 +1,55 @@
+---
+title: nsIPrompt
+slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIPrompt
+translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIPrompt
+---
+<p></p><div style="border: solid #ddd 2px; margin-bottom: 12px;">
+<div style="background: #eee; padding: 2px;"><code><a href="https://dxr.mozilla.org/mozilla-central/source/netwerk/base/public/nsIPrompt.idl" rel="custom">netwerk/base/public/nsIPrompt.idl</a></code><span style="text-align: right; float: right;"><a href="/zh-CN/docs/Interfaces/About_Scriptable_Interfaces" style="color: #00cc00; font-weight: 700;">脚本化</a></span></div>
+<span style="padding: 4px 2px;">
+
+This is the prompt interface which can be used without knowledge of a parent window. The parentage is hidden by the <code>GetInterface</code> though which it is obtained.
+</span>
+
+<div style="background: #eee; padding: 2px;">
+继承于: <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupports" title="">nsISupports</a></code>
+<span style="text-align: right; float: right;">最后修改于Gecko 1.8 (Firefox 1.5 / Thunderbird 1.5 / SeaMonkey 1.0)</span></div>
+</div><p></p>
+<div class="note">
+ <strong>注:</strong> 本接口基本等价于<code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIPromptService" title="">nsIPromptService</a></code>,只是没有parent <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMWindow" title="">nsIDOMWindow</a></code>这个参数.为了避免重复的文档,下面的所有方法都链接到了<code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIPromptService" title="">nsIPromptService</a></code>.如果你准备使用这个接口,一定要删除那些方法中的<code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMWindow" title="">nsIDOMWindow</a></code>参数.</div>
+<p>Normally you would use the prompt service as it is more flexible, but sometimes a callback will request an <code>nsIPrompt</code> via <code><a href="https://developer.mozilla.org/zh-CN/docs/XPCOM_Interface_Reference/nsIInterfaceRequestor#getInterface()">nsIInterfaceRequestor.getInterface()</a></code>. To get an instance, call the <code><a href="https://developer.mozilla.org/zh-CN/docs/XPCOM_Interface_Reference/nsIWindowWatcher#getNewPrompter()">nsIWindowWatcher.getNewPrompter()</a></code>.</p>
+<h2 id="Method_overview" name="Method_overview">方法概述</h2>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>void <a href="/zh-CN/docs/XPCOM_Interface_Reference/nsIPromptService#alert()" title="en/XPCOM_Interface_Reference/nsIPromptService#alert()">alert</a>(in wstring dialogTitle, in wstring text);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="/zh-CN/docs/XPCOM_Interface_Reference/nsIPromptService#alertCheck()" title="en/XPCOM_Interface_Reference/nsIPromptService#alertCheck()">alertCheck</a>(in wstring dialogTitle, in wstring text, in wstring checkMsg, inout boolean checkValue);</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="/zh-CN/docs/XPCOM_Interface_Reference/nsIPromptService#confirm()" title="en/XPCOM_Interface_Reference/nsIPromptService#confirm()">confirm</a>(in wstring dialogTitle, in wstring text);</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="/zh-CN/docs/XPCOM_Interface_Reference/nsIPromptService#confirmCheck()" title="en/XPCOM_Interface_Reference/nsIPromptService#confirmCheck()">confirmCheck</a>(in wstring dialogTitle, in wstring text, in wstring checkMsg, inout boolean checkValue);</code></td>
+ </tr>
+ <tr>
+ <td><code>PRInt32 <a href="/zh-CN/docs/XPCOM_Interface_Reference/nsIPromptService#confirmEx()" title="en/XPCOM_Interface_Reference/nsIPromptService#confirmEx()">confirmEx</a>(in wstring dialogTitle, in wstring text, in unsigned long buttonFlags, in wstring button0Title, in wstring button1Title, in wstring button2Title, in wstring checkMsg, inout boolean checkValue);</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="/zh-CN/docs/XPCOM_Interface_Reference/nsIPromptService#prompt()" title="en/XPCOM_Interface_Reference/nsIPromptService#prompt()">prompt</a>(in wstring dialogTitle, in wstring text, inout wstring value, in wstring checkMsg, inout boolean checkValue);</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="/zh-CN/docs/XPCOM_Interface_Reference/nsIPromptService#promptPassword()" title="en/XPCOM_Interface_Reference/nsIPromptService#promptPassword()">promptPassword</a>(in wstring dialogTitle, in wstring text, inout wstring password, in wstring checkMsg, inout boolean checkValue);</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="/zh-CN/docs/XPCOM_Interface_Reference/nsIPromptService#promptUsernameAndPassword()" title="en/XPCOM_Interface_Reference/nsIPromptService#promptUsernameAndPassword()">promptUsernameAndPassword</a>(in wstring dialogTitle, in wstring text, inout wstring username, inout wstring password, in wstring checkMsg, inout boolean checkValue);</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="/zh-CN/docs/XPCOM_Interface_Reference/nsIPromptService#select()" title="en/XPCOM_Interface_Reference/nsIPromptService#select()">select</a>(in wstring dialogTitle, in wstring text, in PRUint32 count, [array, size_is(count)] in wstring selectList, out long outSelection);</code></td>
+ </tr>
+ </tbody>
+</table>
+<h2 id="Constants" name="Constants">常量</h2>
+<p><code>nsIPrompt中的</code>按钮标识同样等同于<code><a href="https://developer.mozilla.org/zh-CN/docs/XPCOM_Interface_Reference/nsIPromptService#Constants">nsIPromptService.Constants</a></code>中定义的那些.示例代码可以在这里找到: <a href="/zh-CN/docs/XPCOM_Interface_Reference/nsIPromptService#Using_the_button_flags" title="en/XPCOM_Interface_Reference/nsIPromptService#Using_the_button_flags">使用按钮标识</a></p>
+<h2 id="相关链接">相关链接</h2>
+<p><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIPromptService" title="">nsIPromptService</a></code></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsipromptservice/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsipromptservice/index.html
new file mode 100644
index 0000000000..b194faca6b
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsipromptservice/index.html
@@ -0,0 +1,696 @@
+---
+title: nsIPromptService
+slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIPromptService
+translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIPromptService
+---
+<p></p><div style="border: solid #ddd 2px; margin-bottom: 12px;">
+<div style="background: #eee; padding: 2px;"><code><a href="https://dxr.mozilla.org/mozilla-central/source/embedding/components/windowwatcher/public/nsIPromptService.idl" rel="custom">embedding/components/windowwatcher/public/nsIPromptService.idl</a></code><span style="text-align: right; float: right;"><a href="/zh-CN/docs/Interfaces/About_Scriptable_Interfaces" style="color: #00cc00; font-weight: 700;">脚本化</a></span></div>
+<span style="padding: 4px 2px;">该接口用来显示一些简单的对话框.在chrome上下文,你应该使用该接口的所属方法来替代常规的DOM方法,例如 <a href="/zh-CN/docs/Web/API/Window/alert" title='显示一个警告对话框,上面显示有指定的文本内容以及一个"确定"按钮。'><code>window.alert</code></a>, <a href="/zh-CN/docs/Web/API/Window/confirm" title="Window.confirm() 方法显示一个具有一个可选消息和两个按钮(确定和取消)的模态对话框 。"><code>window.confirm</code></a>, 等.</span>
+
+<div style="background: #eee; padding: 2px;">
+继承于: <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupports" title="">nsISupports</a></code>
+<span style="text-align: right; float: right;">最后修改于Gecko 1.7.5 </span></div>
+</div><p></p>
+<p>You can define access keys (or keyboard shortcuts) for buttons by including an ampersand ("&amp;") in front of the character that should be the access key for that button. If you need to include an ampersand in the button's text, use two of them, like this: "&amp;&amp;".</p>
+<div class="note">
+ <strong>Note:</strong> Some of these interface methods use <code>out</code> and <code>inout</code> parameters. In C++, <code>out</code> parameters are pointers. For JavaScript, they are extra work, as you can't use an <code>out</code> parameter directly. You need to wrap them in a temporary object, which can be either empty or have a <code>value</code> property set to the <code>out</code> parameter type. For more information on out parameters and JavaScript refer to <a href="/zh-cn/Working_with_out_parameters" title="zh-cn/Working with out parameters">Working with out parameters</a>.</div>
+<p>该接口由: <code>@mozilla.org/embedcomp/prompt-service;1</code> 组件实现,下面的代码可以得到一个promptService对象实例:</p>
+<pre>var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+ .getService(Components.interfaces.nsIPromptService);
+</pre>
+<h2 id="Method_overview" name="Method_overview">方法概述</h2>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>void <a href="#alert()">alert</a>(in <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMWindow" title="">nsIDOMWindow</a></code> aParent, in wstring aDialogTitle, in wstring aText);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="#alertCheck()">alertCheck</a>(in <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMWindow" title="">nsIDOMWindow</a></code> aParent, in wstring aDialogTitle, in wstring aText, in wstring aCheckMsg, inout boolean aCheckState);</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#confirm()">confirm</a>(in <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMWindow" title="">nsIDOMWindow</a></code> aParent, in wstring aDialogTitle, in wstring aText);</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#confirmCheck()">confirmCheck</a>(in <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMWindow" title="">nsIDOMWindow</a></code> aParent, in wstring aDialogTitle, in wstring aText, in wstring aCheckMsg, inout boolean aCheckState);</code></td>
+ </tr>
+ <tr>
+ <td><code>PRInt32 <a href="#confirmEx()">confirmEx</a>(in <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMWindow" title="">nsIDOMWindow</a></code> aParent,in wstring aDialogTitle,in wstring aText, in unsigned long aButtonFlags,in wstring aButton0Title, in wstring aButton1Title,in wstring aButton2Title,in wstring aCheckMsg, inout boolean aCheckState);</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#prompt()">prompt</a>(in <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMWindow" title="">nsIDOMWindow</a></code> aParent, in wstring aDialogTitle, in wstring aText, inout wstring aValue, in wstring aCheckMsg, inout boolean aCheckState);</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#promptUsernameAndPassword()">promptUsernameAndPassword</a>(in <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMWindow" title="">nsIDOMWindow</a></code> aParent, in wstring aDialogTitle, in wstring aText, inout wstring aUsername, inout wstring aPassword, in wstring aCheckMsg, inout boolean aCheckState);</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#promptPassword()">promptPassword</a>(in <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMWindow" title="">nsIDOMWindow</a></code> aParent, in wstring aDialogTitle, in wstring aText, inout wstring aPassword, in wstring aCheckMsg, inout boolean aCheckState);</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#select()">select</a>(in <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIDOMWindow" title="">nsIDOMWindow</a></code> aParent, in wstring aDialogTitle, in wstring aText, in PRUint32 aCount, [array, size_is(aCount)] in wstring aSelectList, out long aOutSelection);</code></td>
+ </tr>
+ </tbody>
+</table>
+<h2 id="Constants" name="Constants">常量</h2>
+<p>The following flags are combined to form the <code>aButtonFlags</code> parameter passed to <a href="#confirmEx">confirmEx</a>. All flags are defined as <code>unsigned long</code> constants and can be accessed as <code>Components.interfaces.nsIPromptService.<em>flagname</em></code> from JavaScript and as nsIPromptService::<code><em>flagname</em></code> from C++.</p>
+<h3 id="Button_position_flags">Button position flags</h3>
+<p>On Linux and Mac, button 2 is on the left of the prompt, while buttons 1 and 0 are on the right. On Windows and OS/2, the buttons are centred in the order 0, 2, 1.</p>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">Constant</td>
+ <td class="header">Value</td>
+ <td class="header">Description</td>
+ </tr>
+ <tr>
+ <td><code>BUTTON_POS_0</code></td>
+ <td><code>1</code></td>
+ <td>This is usually the button used to confirm the prompt. It typically has the label "OK", "Yes" or "Save".</td>
+ </tr>
+ <tr>
+ <td><code>BUTTON_POS_1</code></td>
+ <td><code>256</code></td>
+ <td>This is the button used to cancel the prompt. It typically has the label "Cancel" or "No". It is equivalent to pressing the Escape key (or Cmd+. on the Mac), or closing the window through the OS controls.</td>
+ </tr>
+ <tr>
+ <td><code>BUTTON_POS_2</code></td>
+ <td><code>65536</code></td>
+ <td>This button can be used to give the user a choice of options, but still allowing the user to cancel the prompt. For instance, it might have the label "Don't Save".</td>
+ </tr>
+ </tbody>
+</table>
+<h3 id="Button_title_flags">Button title flags</h3>
+<p>These flags are used along with <a href="#Button_position_flags">Button position flags</a> to set the labels of buttons in the prompt.</p>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">Constant</td>
+ <td class="header">Value</td>
+ <td class="header">Description</td>
+ </tr>
+ <tr>
+ <td><code>BUTTON_TITLE_OK</code></td>
+ <td><code>1</code></td>
+ <td rowspan="7"> These flags are used to select standard labels from the user's current locale.</td>
+ </tr>
+ <tr>
+ <td><code>BUTTON_TITLE_CANCEL</code></td>
+ <td><code>2</code></td>
+ </tr>
+ <tr>
+ <td><code>BUTTON_TITLE_YES</code></td>
+ <td><code>3</code></td>
+ </tr>
+ <tr>
+ <td><code>BUTTON_TITLE_NO</code></td>
+ <td><code>4</code></td>
+ </tr>
+ <tr>
+ <td><code>BUTTON_TITLE_SAVE</code></td>
+ <td><code>5</code></td>
+ </tr>
+ <tr>
+ <td><code>BUTTON_TITLE_DONT_SAVE</code></td>
+ <td><code>6</code></td>
+ </tr>
+ <tr>
+ <td><code>BUTTON_TITLE_REVERT</code></td>
+ <td><code>7</code></td>
+ </tr>
+ <tr>
+ <td><code>BUTTON_TITLE_IS_STRING</code></td>
+ <td><code>127</code></td>
+ <td>This flag indicates that the label is passed as a separate string. Use this for labels that don't match one of the constants above.</td>
+ </tr>
+ </tbody>
+</table>
+<h3 id="Button_default_flags">Button default flags</h3>
+<p>These flags are used to select which button is the default.</p>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">Constant</td>
+ <td class="header">Value</td>
+ <td class="header">Description</td>
+ </tr>
+ <tr>
+ <td>BUTTON_POS_0_DEFAULT</td>
+ <td>0</td>
+ <td> </td>
+ </tr>
+ <tr>
+ <td>BUTTON_POS_1_DEFAULT</td>
+ <td>16777216</td>
+ <td> </td>
+ </tr>
+ <tr>
+ <td>BUTTON_POS_2_DEFAULT</td>
+ <td>33554432</td>
+ <td> </td>
+ </tr>
+ </tbody>
+</table>
+<h3 id="BUTTON_DELAY_ENABLE">BUTTON_DELAY_ENABLE</h3>
+<p><code>BUTTON_DELAY_ENABLE</code> causes the buttons to be initially disabled. They are enabled after a timeout expires. The implementation may interpret this loosely, as the intent is to ensure that the user does not click through a security dialog too quickly. Strictly speaking, the implementation could choose to ignore this flag. A delay can be useful not only to give the user more time to think before acting, but also as a countermeasure against malicious web sites that intentionally create a race condition whereby the user intends to click or type a key responding, for example, to the web site's prompt but the security dialog pops up unexpectedly and its button is unintentionally activated.</p>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">Constant</td>
+ <td class="header">Value</td>
+ <td class="header">Description</td>
+ </tr>
+ <tr>
+ <td>BUTTON_DELAY_ENABLE</td>
+ <td>67108864</td>
+ <td> </td>
+ </tr>
+ </tbody>
+</table>
+<h3 id="Standard_Buttons_flags">Standard Buttons flags</h3>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">Constant</td>
+ <td class="header">Value</td>
+ <td class="header">Description</td>
+ </tr>
+ <tr>
+ <td><code>STD_OK_CANCEL_BUTTONS</code></td>
+ <td>513</td>
+ <td>
+ <p>selects the standard set of OK/Cancel buttons.</p>
+ <code>(BUTTON_TITLE_OK *BUTTON_POS_0) +(BUTTON_TITLE_CANCEL * BUTTON_POS_1)</code></td>
+ </tr>
+ <tr>
+ <td><code>STD_YES_NO_BUTTONS</code></td>
+ <td>1027</td>
+ <td>
+ <p>selects the standard set of Yes/No buttons.</p>
+ <code>(BUTTON_TITLE_YES *BUTTON_POS_0) +(BUTTON_TITLE_NO * BUTTON_POS_1)</code></td>
+ </tr>
+ </tbody>
+</table>
+<h2 id="Methods" name="Methods">方法</h2>
+<h3 id="alert()">alert()</h3>
+<p><code>alert</code> 方法显示一个警告对话框,包含一个确认按钮. 除了可以设置对话框的标题以外,效果和<a href="/zh-CN/docs/Web/API/Window/alert" title='显示一个警告对话框,上面显示有指定的文本内容以及一个"确定"按钮。'><code>window.alert</code></a>全都相同 . 在chrome上下文,你应该使用该xpcom方法来替代<code>window.alert</code>.</p>
+<pre>void alert(
+ in nsIDOMWindow aParent,
+ in wstring aDialogTitle,
+ in wstring aText
+);
+</pre>
+<h6 id="Parameters" name="Parameters">参数</h6>
+<dl>
+ <dt>
+ <code>aParent</code></dt>
+ <dd>
+ 对话框的父窗口,如果该值设为 <code>null</code>,则父窗口为当前激活的窗口 <code>nsIWindowWatcher.activeWindow</code>.</dd>
+ <dt>
+ <code>aDialogTitle</code></dt>
+ <dd>
+ 对话框的标题文字.</dd>
+ <dt>
+ <code>aText</code></dt>
+ <dd>
+ 对话框的内容文字.</dd>
+</dl>
+<p>代码示例:<a href="#alert_example">alert_example</a>.</p>
+<h3 id="alertCheck()">alertCheck()</h3>
+<p>显示一个警告对话框,包含一个确认按钮和一个复选框.</p>
+<pre>void alertCheck(
+ in nsIDOMWindow aParent,
+ in wstring aDialogTitle,
+ in wstring aText,
+ in wstring aCheckMsg,
+ inout boolean aCheckState
+);
+</pre>
+<h6 id="Parameters" name="Parameters">参数</h6>
+<dl>
+ <dt>
+ <code>aParent</code></dt>
+ <dd>
+ 对话框的父窗口,如果该值设为 <code>null</code>,则父窗口为当前激活的窗口 <code>nsIWindowWatcher.activeWindow</code>..</dd>
+ <dt>
+ <code>aDialogTitle</code></dt>
+ <dd>
+ 对话框的标题文字.</dd>
+ <dt>
+ <code>aText</code></dt>
+ <dd>
+ 对话框的内容文字.</dd>
+ <dt>
+ <code>aCheckMsg</code></dt>
+ <dd>
+ 复选框的说明文字.</dd>
+ <dt>
+ <code>aCheckState</code></dt>
+ <dd>
+ 该变量是一个对象引用,当对话框打开时,变量的value属性控制了复选框的初始选择状态.当对话框关闭时,变量的value属性会存储下复选框的最后选择状态.该变量初始化时可以包含一个类型为布尔值的value属性或者是空对象.</dd>
+</dl>
+<p>代码示例:<a href="#alertCheck_example">alertCheck_example</a>.</p>
+<h3 id="confirm()">confirm()</h3>
+<p>显示一个确认对话框,包含一个确认按钮和一个取消按钮.</p>
+<pre>boolean confirm(
+ in nsIDOMWindow aParent,
+ in wstring aDialogTitle,
+ in wstring aText
+);
+</pre>
+<h6 id="Parameters" name="Parameters">参数</h6>
+<dl>
+ <dt>
+ <code>aParent</code></dt>
+ <dd>
+ 对话框的父窗口,如果该值设为 <code>null</code>,则父窗口为当前激活的窗口 <code>nsIWindowWatcher.activeWindow</code>.</dd>
+ <dt>
+ <code>aDialogTitle</code></dt>
+ <dd>
+ 对话框的标题文字.</dd>
+ <dt>
+ <code>aText</code></dt>
+ <dd>
+ 对话框的内容文字.</dd>
+</dl>
+<h6 id="Return_value" name="Return_value">返回值</h6>
+<dl>
+ <dd>
+ 点确定按钮返回 <code>true</code> , 点取消按钮返回 <code>false</code></dd>
+</dl>
+<p>代码示例:<a href="#confirm_example">confirm_example</a>.</p>
+<h3 id="confirmCheck()">confirmCheck()</h3>
+<p>显示一个对话框,包含一个确认按钮,一个取消按钮和一个复选框.</p>
+<p>代码示例:<a href="#confirm_example">confirm_example</a>.</p>
+<pre>boolean confirmCheck(
+ in nsIDOMWindow aParent,
+ in wstring aDialogTitle,
+ in wstring aText,
+ in wstring aCheckMsg,
+ inout boolean aCheckState
+);
+</pre>
+<h6 id="Parameters" name="Parameters">参数</h6>
+<dl>
+ <dt>
+ <code>aParent</code></dt>
+ <dd>
+ 对话框的父窗口,如果该值设为 <code>null</code>,则父窗口为当前激活的窗口 <code>nsIWindowWatcher.activeWindow</code>.</dd>
+ <dt>
+ <code>aDialogTitle</code></dt>
+ <dd>
+ 对话框的标题文字.</dd>
+ <dt>
+ <code>aText</code></dt>
+ <dd>
+ 对话框的内容文字.</dd>
+ <dt>
+ <code>aCheckMsg</code></dt>
+ <dd>
+ 复选框的说明文字.</dd>
+ <dt>
+ <code>aCheckState</code></dt>
+ <dd>
+ 该变量是一个对象引用,当对话框打开时,变量的value属性控制了复选框的初始选择状态.当对话框关闭时,变量的value属性会存储下复选框的最后选择状态.该变量初始化时可以包含一个类型为布尔值的value属性或者是空对象.</dd>
+</dl>
+<h6 id="Return_value" name="Return_value">返回值</h6>
+<dl>
+ <dd>
+ 点确定按钮返回 <code>true</code> , 点取消按钮返回 <code>false</code></dd>
+</dl>
+<h3 id="confirmEx()">confirmEx()</h3>
+<p>Puts up a dialog with up to 3 buttons and an optional, labeled checkbox.</p>
+<p>The Buttons are numbered 0 - 2. The implementation can decide what order the buttons appear in, and it may not be simply right-to-left (2, 1, 0) or left-to-right (0, 1, 2). See <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=624043" title="nsIPromptService.confirmEx : buttons show up in the order 0,2,1 instead of 0,1,2">bug 624043</a> for more on this. Button 0 is the default button unless one of the Button Default Flags is specified (see <a href="/zh-cn/XPCOM_Interface_Reference/nsIPromptService#Button_default_flags" title="https://developer.mozilla.org/zh-cn/XPCOM_Interface_Reference/nsIPromptService#Button_default_flags">Button default flags</a>).</p>
+<p>A button may use a predefined title, specified by one of the Button Title Flags values. Each title value can be multiplied by a position value to assign the title to a particular button. If BUTTON_TITLE_IS_STRING is used for a button, the string parameter for that button will be used. If the value for a button position is zero, the button will not be shown.</p>
+<p>The following Example creates a Dialog with an OK button an an custom button description.</p>
+<p><code>aButtonFlags = (BUTTON_POS_0) * (BUTTON_TITLE_OK) +<br>
+ (BUTTON_POS_1) * (BUTTON_TITLE_IS_STRING) +<br>
+ BUTTON_POS_1_DEFAULT; </code></p>
+<div class="note">
+ confirmEx always returns 1 if the user closes the window using the close button in the titlebar! <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=345067" title="Issues with prompt service's confirmEx - confirmEx always returns 1 when user closes dialog window using the X button in titlebar">bug 345067</a></div>
+<pre>PRInt32 confirmEx(
+ in nsIDOMWindow aParent,
+ in wstring aDialogTitle,
+ in wstring aText,
+ in unsigned long aButtonFlags,
+ in wstring aButton0Title,
+ in wstring aButton1Title,
+ in wstring aButton2Title,
+ in wstring aCheckMsg,
+ inout boolean aCheckState
+);
+</pre>
+<h6 id="Parameters" name="Parameters">参数</h6>
+<dl>
+ <dt>
+ <code>aParent</code></dt>
+ <dd>
+ 对话框的父窗口,如果该值设为 <code>null</code>,则父窗口为当前激活的窗口 <code>nsIWindowWatcher.activeWindow</code>.</dd>
+ <dt>
+ <code>aDialogTitle</code></dt>
+ <dd>
+ 对话框的标题文字.</dd>
+ <dt>
+ <code>aText</code></dt>
+ <dd>
+ 对话框的内容文字.</dd>
+ <dt>
+ <code>aButtonFlags</code></dt>
+ <dd>
+ <code>aButtonFlags</code> is a combination of <a href="#Button_flags">Button flags</a> as described in <a href="#Using_the_button_flags">Using the button flags</a> below.</dd>
+ <dt>
+ <code>aButton0Title</code></dt>
+ <dd>
+ caption displayed for button 0 if<code>(BUTTON_TITLE_IS_STRING*</code><code>BUTTON_TITLE_POS_0)</code> flags are set in aButtonFlags</dd>
+ <dt>
+ <code>aButton1Title</code></dt>
+ <dd>
+ caption displayed for button 1 if<code>(BUTTON_TITLE_IS_STRING*</code><code>BUTTON_TITLE_POS_1)</code> flags are set in aButtonFlags</dd>
+ <dt>
+ <code>aButton2Title</code></dt>
+ <dd>
+ caption displayed for button 2 if<code>(BUTTON_TITLE_IS_STRING*</code><code>BUTTON_TITLE_POS_2)</code> flags are set in aButtonFlags</dd>
+ <dt>
+ <code>aCheckMsg</code></dt>
+ <dd>
+  复选框的说明文字. 如果值设为Null,则复选框不会显示.</dd>
+ <dt>
+ <code>aCheckState</code></dt>
+ <dd>
+ 该变量是一个对象引用,当对话框打开时,变量的value属性控制了复选框的初始选择状态.当对话框关闭时,变量的value属性会存储下复选框的最后选择状态.该变量初始化时可以包含一个类型为布尔值的value属性或者是空对象.</dd>
+</dl>
+<h6 id="Return_value" name="Return_value">返回值</h6>
+<dl>
+ <dd>
+ 按下按钮的索引.</dd>
+</dl>
+<h3 id="prompt()">prompt()</h3>
+<p>显示一个对话框,包含一个文本框,一个可选的复选框.</p>
+<p>代码示例:<a href="#prompt_example">prompt_example</a>.</p>
+<pre>boolean prompt(
+ in nsIDOMWindow aParent,
+ in wstring aDialogTitle,
+ in wstring aText,
+ inout wstring aValue,
+ in wstring aCheckMsg,
+ inout boolean aCheckState
+);
+</pre>
+<h6 id="Parameters" name="Parameters">参数</h6>
+<dl>
+ <dt>
+ <code>aParent</code></dt>
+ <dd>
+ 对话框的父窗口,如果该值设为 <code>null</code>,则父窗口为当前激活的窗口 <code>nsIWindowWatcher.activeWindow</code>.</dd>
+ <dt>
+ <code>aDialogTitle</code></dt>
+ <dd>
+ 对话框的标题文字.</dd>
+ <dt>
+ <code>aText</code></dt>
+ <dd>
+ 对话框的内容文字.</dd>
+ <dt>
+ <code>aValue</code></dt>
+ <dd>
+ 该变量是一个对象引用,当对话框打开时,变量的value属性值就是文本输入框的的初始值.当用户点击确认按钮关闭对话框时,变量的value属性会存储下文本输入框的最后确定值.其他方法关闭对话框时,变量的value属性值不会改变.该变量初始化时可以包含一个类型为字符串值的value属性或者是空对象.</dd>
+ <dt>
+ <code>aCheckMsg</code></dt>
+ <dd>
+ 复选框的说明文字. 如果值设为Null,则复选框不会显示.</dd>
+ <dt>
+ <code>aCheckState</code></dt>
+ <dd>
+ 该变量是一个对象引用,当对话框打开时,变量的value属性控制了复选框的初始选择状态.当对话框关闭时,变量的value属性会存储下复选框的最后选择状态.该变量初始化时可以包含一个类型为布尔值的value属性或者是空对象.</dd>
+</dl>
+<h6 id="Return_value" name="Return_value">返回值</h6>
+<dl>
+ <dd>
+ 点确定按钮返回 <code>true</code> , 点取消按钮返回 <code>false</code></dd>
+</dl>
+<h3 id="promptUsernameAndPassword()">promptUsernameAndPassword()</h3>
+<p>显示一个对话框,内部包含一个文本输入框,一个密码输入框,和一个可选的复选框.</p>
+<p>代码示例:<a href="#promptUsernameAndPassword_example">promptUsernameAndPassword_example</a>.</p>
+<pre>boolean promptUsernameAndPassword(
+ in nsIDOMWindow aParent,
+ in wstring aDialogTitle,
+ in wstring aText,
+ inout wstring aUsername,
+ inout wstring aPassword,
+ in wstring aCheckMsg,
+ inout boolean aCheckState
+);
+</pre>
+<h6 id="Parameters" name="Parameters">参数</h6>
+<dl>
+ <dt>
+ <code>aParent</code></dt>
+ <dd>
+ 对话框的父窗口,如果该值设为 <code>null</code>,则父窗口为当前激活的窗口 <code>nsIWindowWatcher.activeWindow</code>.</dd>
+ <dt>
+ <code>aDialogTitle</code></dt>
+ <dd>
+ 对话框的标题文字.</dd>
+ <dt>
+ <code>aText</code></dt>
+ <dd>
+ 对话框的内容文字.</dd>
+ <dt>
+ <code>aUsername</code></dt>
+ <dd>
+ 该变量是一个对象引用,当对话框打开时,变量的value属性值就是用户名输入框的的初始值.当用户点击确认按钮关闭对话框时,变量的value属性会存储下用户名输入框的最后确定值.其他方法关闭对话框时,变量的value属性值不会改变.该变量初始化时可以包含一个类型为字符串值的value属性或者是空对象.</dd>
+ <dt>
+ <code>aPassword</code></dt>
+ <dd>
+ 该变量是一个对象引用,当对话框打开时,变量的value属性值就是密码输入框的的初始值.当用户点击确认按钮关闭对话框时,变量的value属性会存储下密码输入框的最后确定值.其他方法关闭对话框时,变量的value属性值不会改变.该变量初始化时可以包含一个类型为字符串值的value属性或者是空对象.</dd>
+ <dt>
+ <code>aCheckMsg</code></dt>
+ <dd>
+ 复选框的说明文字. 如果值设为Null,则复选框不会显示.</dd>
+ <dt>
+ <code>aCheckState</code></dt>
+ <dd>
+ 该变量是一个对象引用,当对话框打开时,变量的value属性控制了复选框的初始选择状态.当对话框关闭时,变量的value属性会存储下复选框的最后选择状态.该变量初始化时可以包含一个类型为布尔值的value属性或者是空对象.</dd>
+</dl>
+<h6 id="Return_value" name="Return_value">返回值</h6>
+<dl>
+ <dd>
+ 点确定按钮返回 <code>true</code> , 点取消按钮返回 <code>false</code></dd>
+</dl>
+<h3 id="promptPassword()">promptPassword()</h3>
+<p>显示一个对话框,包含一个密码框,一个可选的复选框.</p>
+<p>代码示例:<a href="#promptPassword_example">promptPassword_example</a>.</p>
+<pre>boolean promptPassword(
+ in nsIDOMWindow aParent,
+ in wstring aDialogTitle,
+ in wstring aText,
+ inout wstring aPassword,
+ in wstring aCheckMsg,
+ inout boolean aCheckState
+);
+</pre>
+<h6 id="Parameters" name="Parameters">参数</h6>
+<dl>
+ <dt>
+ <code>aParent</code></dt>
+ <dd>
+ 对话框的父窗口,如果该值设为 <code>null</code>,则父窗口为当前激活的窗口 <code>nsIWindowWatcher.activeWindow</code>.</dd>
+ <dt>
+ <code>aDialogTitle</code></dt>
+ <dd>
+ 对话框的标题文字.</dd>
+ <dt>
+ <code>aText</code></dt>
+ <dd>
+ 对话框的内容文字.</dd>
+ <dt>
+ <code>aPassword</code></dt>
+ <dd>
+ 该变量是一个对象引用,当对话框打开时,变量的value属性值就是密码输入框的的初始值.当用户点击确认按钮关闭对话框时,变量的value属性会存储下密码输入框的最后确定值.其他方法关闭对话框时,变量的value属性值不会改变.该变量初始化时可以包含一个类型为字符串值的value属性或者是空对象.</dd>
+ <dt>
+ <code>aCheckMsg</code></dt>
+ <dd>
+ 复选框的说明文字. 如果值设为Null,则复选框不会显示.</dd>
+ <dt>
+ <code>aCheckState</code></dt>
+ <dd>
+     该变量是一个对象引用,当对话框打开时,变量的value属性控制了复选框的初始选择状态.当对话框关闭时,变量的value属性会存储下复选框的最后选择状态.该变量初始化时可以包含一个类型为布尔值的value属性或者是空对象.</dd>
+</dl>
+<h6 id="Return_value" name="Return_value">返回值</h6>
+<dl>
+ <dd>
+ 点确定按钮返回 <code>true</code> , 点取消按钮返回 <code>false</code></dd>
+</dl>
+<h3 id="select()">select()</h3>
+<p>显示一个对话框,包含一个单项选择的字符串列表.</p>
+<p>代码示例:<a href="#select_example">select_example</a>.</p>
+<pre>boolean select(
+ in nsIDOMWindow aParent,
+ in wstring aDialogTitle,
+ in wstring aText,
+ in PRUint32 aCount,
+ [array, size_is(aCount)] in wstring aSelectList,
+ out long aOutSelection
+);
+</pre>
+<dl>
+ <dt>
+ <code>aParent</code></dt>
+ <dd>
+ 对话框的父窗口,如果该值设为 <code>null</code>,则父窗口为当前激活的窗口 <code>nsIWindowWatcher.activeWindow</code>.</dd>
+ <dt>
+ <code>aDialogTitle</code></dt>
+ <dd>
+ 对话框的标题文字.</dd>
+ <dt>
+ <code>aText</code></dt>
+ <dd>
+ 对话框的内容文字.</dd>
+ <dt>
+ <code>aCount</code></dt>
+ <dd>
+ 参数aSelectList的数组长度.</dd>
+ <dt>
+ <code>aSelectList</code></dt>
+ <dd>
+ 构成字符串列表的字符串数组.</dd>
+ <dt>
+ <code>aOutSelection</code></dt>
+ <dd>
+ 该变量是一个对象引用,当用户选择某个项目后,变量的value属性值存储了用户所选列表项目的索引值.</dd>
+</dl>
+<h6 id="Return_value" name="Return_value">返回值</h6>
+<dl>
+ <dd>
+ 点确定按钮返回 <code>true</code> , 点取消按钮返回 <code>false</code></dd>
+</dl>
+<h2 id="代码示例">代码示例</h2>
+<p> </p>
+<h3 id="alert_example">alert example</h3>
+<p><a href="#alert()">alert()</a> 显示一个简单的对话框.</p>
+<p><img alt="" class="internal" src="/@api/deki/files/4072/=AlertExample.png" style="width: 365px; height: 129px;"></p>
+<pre class="brush: js">var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+ .getService(Components.interfaces.nsIPromptService);
+
+prompts.alert(null, "Title of this Dialog", "Hello! You have now been alerted.");
+</pre>
+<h3 id="alertCheck_example">alertCheck example</h3>
+<p><a href="#alertCheck()">alertCheck()</a> 显示一个包含复选框的对话框</p>
+<p><img alt="" class="internal" src="/@api/deki/files/4073/=AlertCheckExample.png" style="width: 365px; height: 152px;"></p>
+<pre class="brush: js">var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+ .getService(Components.interfaces.nsIPromptService);
+
+var check = {value: false}; // default the checkbox to false
+
+prompts.alertCheck(null, "Title of this Dialog", "Hello! You have now been alerted.",
+ "And this is a checkbox", check);
+
+// check.value is now true if the box was checked and false if the box was cleared
+</pre>
+<h3 id="confirm_example">confirm example</h3>
+<p><a href="#confirm()">confirm()</a> 显示一个提示框,内部包含一个确认按钮和一个取消按钮.</p>
+<pre class="brush: js">var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+ .getService(Components.interfaces.nsIPromptService);
+
+var result = prompts.confirm(null, "Title of this Dialog", "Are you sure?");
+
+// result is now true if OK was clicked, and false if cancel was clicked
+</pre>
+<h3 id="confirmCheck_example">confirmCheck example</h3>
+<p><a href="#confirmCheck">confirmCheck</a> 显示一个提示框,内部包含一个确认按钮,一个取消按钮,一个复选框.</p>
+<pre class="brush: js">var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+ .getService(Components.interfaces.nsIPromptService);
+
+var check = {value: true}; // default the checkbox to true
+
+var result = prompts.confirmCheck(null, "Title of this Dialog", "Are you sure?",
+ "Don't ask again", check);
+
+// check.value is now true if the box was checked AND OK was pressed, false if
+// the box was cleared AND OK was pressed, and is the default of true if Cancel was pressed.
+</pre>
+<h3 id="confirmEx_example">confirmEx example</h3>
+<p><a href="#confirmEx()">confirmEx()</a>  显示一个对话框,内部包含三个或三个以下的按纽,和一个可选的复选框.</p>
+<p><img alt="" class="internal" src="/@api/deki/files/4075/=confirmExExample.png" style="width: 365px; height: 129px;"></p>
+<pre class="brush: js">var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+ .getService(Components.interfaces.nsIPromptService);
+
+var check = {value: false}; // default the checkbox to false
+
+var flags = prompts.BUTTON_POS_0 * prompts.BUTTON_TITLE_SAVE +
+ prompts.BUTTON_POS_1 * prompts.BUTTON_TITLE_IS_STRING +
+ prompts.BUTTON_POS_2 * prompts.BUTTON_TITLE_CANCEL;
+// This value of flags will create 3 buttons. The first will be "Save", the
+// second will be the value of aButtonTitle1, and the third will be "Cancel"
+
+var button = prompts.confirmEx(null, "Title of this Dialog", "What do you want to do?",
+ flags, "", "Button 1", "", null, check);
+
+// The checkbox will be hidden, and button will contain the index of the button pressed,
+// 0, 1, or 2.
+</pre>
+<h3 id="prompt_example">prompt example</h3>
+<p><a href="#prompt()">prompt()</a> 显示一个对话框,内部包含一个文本输入框.</p>
+<pre class="brush: js">var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+ .getService(Components.interfaces.nsIPromptService);
+
+var check = {value: false}; // default the checkbox to false
+
+var input = {value: "Bob"}; // default the edit field to Bob
+
+var result = prompts.prompt(null, "Title", "What is your name?", input, null, check);
+
+// result is true if OK is pressed, false if Cancel. input.value holds the value of the edit field if "OK" was pressed.
+</pre>
+<h3 id="promptUsernameAndPassword_example">promptUsernameAndPassword example</h3>
+<p><a href="#promptUsernameAndPassword()">promptUsernameAndPassword()</a> 显示一个对话框,内部包含一个文本输入框,一个密码输入框和一个可选的复选框.</p>
+<p><img alt="" class="internal" src="/@api/deki/files/4076/=promptUsernameAndPasswordExample.png" style="width: 365px; height: 200px;"></p>
+<pre class="brush: js">var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+ .getService(Components.interfaces.nsIPromptService);
+
+var username = {value: "user"}; // default the username to user
+
+var password = {value: "pass"}; // default the password to pass
+
+var check = {value: true}; // default the checkbox to true
+
+var result = prompts.promptUsernameAndPassword(null, "Title", "Enter username and password:",
+ username, password, "Save", check);
+
+// result is true if OK was pressed, false if cancel was pressed. username.value,
+// password.value, and check.value are set if OK was pressed.
+</pre>
+<h3 id="promptPassword_example">promptPassword example</h3>
+<p><a href="#promptPassword()">promptPassword()</a> 显示一个对话框,内部包含一个密码输入框和一个可选的复选框.</p>
+<pre class="brush: js">var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+ .getService(Components.interfaces.nsIPromptService);
+
+var password = {value: "pass"}; // default the password to pass
+
+var check = {value: true}; // default the checkbox to true
+
+var result = prompts.promptPassword(null, "Title", "Enter password:", password, null, check);
+
+// result is true if OK was pressed, false if cancel was pressed. password.value is
+// set if OK was pressed. The checkbox is not displayed.
+</pre>
+<h3 id="select_example">select example</h3>
+<p><a href="#select()">select()</a> 显示一个对话框,内部是一个包含多个选项的列表框.</p>
+<p><img alt="" class="internal" src="/@api/deki/files/4074/=selectExample.png" style="width: 333px; height: 196px;"></p>
+<pre class="brush: js">var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+ .getService(Components.interfaces.nsIPromptService);
+
+var items = ["Hello", "Welcome", "Howdy", "Hi", ":)"]; // list items
+
+var selected = {};
+
+var result = prompts.select(null, "Title", "What greeting do you want?", items.length,
+ items, selected);
+
+// result is true if OK was pressed, false if cancel. selected is the index of the item array
+// that was selected. Get the item using items[selected.value].
+</pre>
+<h2 id="See_also" name="See_also">相关链接</h2>
+<ul>
+ <li><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIPrompt" title="">nsIPrompt</a></code></li>
+ <li><a href="/zh-cn/Working_with_out_parameters" title="zh-cn/Working with out parameters">Working with out parameters</a></li>
+</ul>
+<p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiscriptableunicodeconverter/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiscriptableunicodeconverter/index.html
new file mode 100644
index 0000000000..fe406f1bba
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiscriptableunicodeconverter/index.html
@@ -0,0 +1,609 @@
+---
+title: nsIScriptableUnicodeConverter
+slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIScriptableUnicodeConverter
+translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIScriptableUnicodeConverter
+---
+<p></p><div style="border: solid #ddd 2px; margin-bottom: 12px;">
+<div style="background: #eee; padding: 2px;"><code><a href="https://dxr.mozilla.org/mozilla-central/source/intl/uconv/idl/nsIScriptableUConv.idl" rel="custom">intl/uconv/idl/nsIScriptableUConv.idl</a></code><span style="text-align: right; float: right;"><a href="/zh-CN/docs/Interfaces/About_Scriptable_Interfaces" style="color: #00cc00; font-weight: 700;">脚本化</a></span></div>
+<span style="padding: 4px 2px;">
+
+This interface is a Unicode encoder for use by scripts.
+</span>
+
+<div style="background: #eee; padding: 2px;">
+继承于: <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupports" title="">nsISupports</a></code>
+<span style="text-align: right; float: right;">最后修改于Gecko 1.8 (Firefox 1.5 / Thunderbird 1.5 / SeaMonkey 1.0)</span></div>
+</div><p></p>
+<p>Implemented by: <code>@mozilla.org/intl/scriptableunicodeconverter</code>. To create an instance, use:</p>
+<pre class="eval">var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
+ .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
+</pre>
+<h2 id="Method_overview" name="Method_overview">Method overview</h2>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>ACString <a href="/zh-cn/XPCOM_Interface_Reference/nsIScriptableUnicodeConverter#ConvertFromUnicode()" title="zh-cn/nsIScriptableUnicodeConverter#ConvertFromUnicode()">ConvertFromUnicode</a>(in AString aSrc);</code></td>
+ </tr>
+ <tr>
+ <td><code>ACString <a href="/zh-cn/XPCOM_Interface_Reference/nsIScriptableUnicodeConverter#Finish()" title="zh-cn/nsIScriptableUnicodeConverter#Finish()">Finish</a>();</code></td>
+ </tr>
+ <tr>
+ <td><code>AString <a href="/zh-cn/XPCOM_Interface_Reference/nsIScriptableUnicodeConverter#ConvertToUnicode()" title="zh-cn/nsIScriptableUnicodeConverter#ConvertToUnicode()">ConvertToUnicode</a>(in ACString aSrc);</code></td>
+ </tr>
+ <tr>
+ <td><code>AString <a href="/zh-cn/XPCOM_Interface_Reference/nsIScriptableUnicodeConverter#convertFromByteArray()" title="zh-cn/nsIScriptableUnicodeConverter#convertFromByteArray()">convertFromByteArray</a>([const,array,size_is(aCount)] in octet aData, in unsigned long aCount);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="/zh-cn/XPCOM_Interface_Reference/nsIScriptableUnicodeConverter#convertToByteArray()" title="zh-cn/nsIScriptableUnicodeConverter#convertToByteArray()">convertToByteArray</a>(in AString aString,[optional] out unsigned long aLen,[array, size_is(aLen),retval] out octet aData);</code></td>
+ </tr>
+ <tr>
+ <td><code><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIInputStream" title="">nsIInputStream</a></code> <a href="/zh-cn/XPCOM_Interface_Reference/nsIScriptableUnicodeConverter#convertToInputStream()" title="zh-cn/nsIScriptableUnicodeConverter#convertToInputStream()">convertToInputStream</a>(in AString aString);</code></td>
+ </tr>
+ </tbody>
+</table>
+<h2 id="Attributes">Attributes</h2>
+<table class="standard-table" style="width: auto;">
+ <tbody>
+ <tr>
+ <td class="header">Attribute</td>
+ <td class="header">Type</td>
+ <td class="header">Description</td>
+ </tr>
+ <tr>
+ <td><code>charset</code></td>
+ <td><code>string</code></td>
+ <td>Current character set. Throws <code>NS_ERROR_UCONV_NOCONV</code> if the requested charset is not supported.</td>
+ </tr>
+ </tbody>
+</table>
+<h2 id="Methods" name="Methods">Methods</h2>
+<h3 id="ConvertFromUnicode()" name="ConvertFromUnicode()">ConvertFromUnicode()</h3>
+<p>Converts the data from Unicode to one Charset. Returns the converted string. After converting, Finish should be called and its return value appended to this return value.</p>
+<pre class="eval">ACString ConvertFromUnicode(
+ in AString aSrc
+);
+</pre>
+<h3 id="Finish()">Finish()</h3>
+<p>Returns the terminator string. Should be called after ConvertFromUnicode() and appended to that function's return value.</p>
+<pre>ACString Finish();
+</pre>
+<h3 id="ConvertToUnicode()">ConvertToUnicode()</h3>
+<p>Converts the data from one Charset to Unicode.</p>
+<pre>AString ConvertToUnicode(
+ in ACString aSrc
+);
+</pre>
+<h3 id="convertFromByteArray()">convertFromByteArray()</h3>
+<p>Converts an array of bytes to a unicode string.</p>
+<pre>AString convertFromByteArray(
+ [const,array,size_is(aCount)] in octet aData,
+ in unsigned long aCount
+);
+</pre>
+<h3 id="convertToByteArray()">convertToByteArray()</h3>
+<p>Convert a unicode string to an array of bytes. Finish does not need to be called.</p>
+<pre>void convertToByteArray(in AString aString,
+ out unsigned long aLen, <span class="inlineIndicator optional optionalInline">可选</span>
+ [array, size_is(aLen),retval] out octet aData
+);
+</pre>
+<h3 id="convertToInputStream()">convertToInputStream()</h3>
+<p>Converts a Unicode string to an input stream. The bytes in the stream are encoded according to the <code>charset</code> attribute. The returned stream is non-blocking.</p>
+<pre>nsIInputStream convertToInputStream(
+  in AString aString
+ );
+</pre>
+<h6 id="Parameters">Parameters</h6>
+<h6 id="Return_value">Return value</h6>
+<p>An <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIInputStream" title="">nsIInputStream</a></code> that will present the text specified in <code>aString</code> as its data.</p>
+<ul>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <ul>
+ <li>
+ <dl>
+ <dt>
+ <code>aString</code></dt>
+ <dd>
+ The text to encode to the stream. The text is encoded into the character set specified by the <code>charset</code> attribute.</dd>
+ </dl>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+</ul>
+<dl>
+</dl>
+<h2 id="Examples" name="Examples">Examples</h2>
+<p>See <a href="/zh-cn/Reading_textual_data" title="zh-cn/Reading_textual_data">Reading textual data</a> and <a href="/zh-cn/Writing_textual_data" title="zh-cn/Writing_textual_data">Writing textual data</a> for examples.</p>
+<p></p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsisyncmessagesender/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsisyncmessagesender/index.html
new file mode 100644
index 0000000000..1af1e116c3
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsisyncmessagesender/index.html
@@ -0,0 +1,65 @@
+---
+title: nsISyncMessageSender
+slug: Mozilla/Tech/XPCOM/Reference/Interface/nsISyncMessageSender
+translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsISyncMessageSender
+---
+<p></p><div style="border: solid #ddd 2px; margin-bottom: 12px;">
+<div style="background: #eee; padding: 2px;"><code><a href="https://dxr.mozilla.org/mozilla-central/source/content/base/public/nsIMessageManager.idl" rel="custom">content/base/public/nsIMessageManager.idl</a></code><span style="text-align: right; float: right;"><a href="/zh-CN/docs/Interfaces/About_Scriptable_Interfaces" style="color: #00cc00; font-weight: 700;">脚本化</a></span></div>
+<span style="padding: 4px 2px;">
+
+Handles sending messages synchronously to a destination frame.
+</span>
+
+ <div style="height: 42px; position: relative; padding: 2px; width: auto;">
+
+ <div style="top: 22px; font-size: 11px; position: absolute;">1.0</div>
+
+ <div style="top: 22px; font-size: 11px; position: absolute; left: 0px; text-align: right; float: right; width: 100%;">66</div>
+
+ <div style="height: 8px; top: 16px; background: #dd0000; left: 0px; position: absolute; width: 11.428571428571429%;"></div>
+
+<div style="height: 8px; top: 16px; left: 11.428571428571429%; background: #00dd00; position: absolute; width: 88.57142857142857%;" title="Introduced in Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1)"></div>
+
+<div style="top: 0px; font-size: 11px; position: absolute; left: 11.428571428571429%;">Introduced</div>
+<div style="top: 22px; font-size: 11px; position: absolute; left: 11.428571428571429%;">Gecko 2.0</div>
+
+</div>
+
+<div style="background: #eee; padding: 2px;">
+继承于: <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFrameMessageManager" title="">nsIFrameMessageManager</a></code>
+<span style="text-align: right; float: right;">最后修改于Gecko 2.0 (Firefox 4 / Thunderbird 3.3 / SeaMonkey 2.1)</span></div>
+</div><p></p>
+<h2 id="Method_overview" name="Method_overview">方法概述</h2>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>void sendSyncMessage(in messageName, in JSON, in [array] jsObjects);</code></td>
+ </tr>
+ </tbody>
+</table>
+<h3 id="sendSyncMessage()">sendSyncMessage()</h3>
+<p>同步发送一条短消息.</p>
+<pre>void sendSyncMessage(
+  in DOMString messageName,
+  in DOMString json,
+);
+</pre>
+<h6 id="Parameters">Parameters</h6>
+<dl>
+ <dt>
+ <code>messageName</code></dt>
+ <dd>
+ 消息的名称.</dd>
+ <dt>
+ <code>json</code></dt>
+ <dd>
+ 一个JSON格式的字符串,代表了要发送的数据.</dd>
+</dl>
+<h2 id="See_also" name="See_also">相关链接</h2>
+<ul>
+ <li><a href="/en/Content_process_event_handling" title="en/Content process event handling">Content process event handling</a></li>
+ <li><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIChromeFrameMessageManager" title="">nsIChromeFrameMessageManager</a></code></li>
+ <li><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIContentFrameMessageManager" title="">nsIContentFrameMessageManager</a></code></li>
+ <li><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFrameLoader" title="">nsIFrameLoader</a></code></li>
+ <li><code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIFrameMessageListener" title="">nsIFrameMessageListener</a></code></li>
+</ul>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsitimer/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsitimer/index.html
new file mode 100644
index 0000000000..24cfb2eb4f
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsitimer/index.html
@@ -0,0 +1,285 @@
+---
+title: nsITimer
+slug: Mozilla/Tech/XPCOM/Reference/Interface/nsITimer
+translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsITimer
+---
+<div id="page-top">
+ <div class="pageText" id="pageText">
+ <p>nsITimer 接口的功能是:在指定延迟后唤醒一个程序。</p>
+ <p><span class="lang lang-en"><code>nsITimer</code> 的定义文档: <span class="lang lang-en"><a class="external" href="http://mxr.mozilla.org/mozilla-central/source/xpcom/threads/nsITimer.idl" rel="external nofollow" title="http://mxr.mozilla.org/mozilla-central/source/xpcom/threads/nsITimer.idl"><code>xpcom/threads/nsITimer.idl</code></a> </span>。It is <span class="lang lang-en"><a href="../../../../en/Interfaces/About_Scriptable_Interfaces" rel="internal">scriptable</a> </span> and <span class="lang lang-en"> <a href="../../../../en/Interfaces/About_Frozen_Interfaces" rel="internal">unfrozen</a> (hasn't changed since 1.9.1) </span>. </span></p>
+ <p>继承自: <span class="lang lang-en"><code><a href="../../../../en/nsISupports" rel="internal">nsISupports</a></code> </span></p>
+ <p>实现: <code>@mozilla.org/timer;1</code>。创建实例如:</p>
+ <pre class="eval">var timer = Components.classes["@mozilla.org/timer;1"]
+ .createInstance(Components.interfaces.nsITimer);
+</pre>
+ <div id="section_1">
+ <h2 class="editable" id="方法预览"><span>方法预览</span></h2>
+ <div class="editIcon">
+ <a href="/../../../../En/NsITimer#" style="" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="../../../../skins/common/icons/icon-trans.gif"></span></a></div>
+ <table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>void <a href="/../../../../En/NsITimer#initWithCallback.28.29" title="../../../../En/NsITimer#initWithCallback.28.29">initWithCallback</a>(in <span class="lang lang-en"><code><a href="../../../../en/nsITimerCallback" rel="internal">nsITimerCallback</a></code> </span> aCallback, in unsigned long aDelay, in unsigned long aType);</code></td>
+ </tr>
+ <tr>
+ <td><code>[noscript] void <a href="/../../../../En/NsITimer#initWithFuncCallback.28.29" title="../../../../En/NsITimer#initWithFuncCallback.28.29">initWithFuncCallback</a>(in <span class="lang lang-en"><code><a class="new" href="../../../../en/nsITimerCallbackFunc" rel="internal">nsITimerCallbackFunc</a></code> </span> aCallback, in voidPtr aClosure, in unsigned long aDelay, in unsigned long aType);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="/../../../../En/NsITimer#init.28.29" title="../../../../En/NsITimer#init.28.29">init</a>(in <span class="lang lang-en"><code><a href="../../../../en/nsIObserver" rel="internal">nsIObserver</a></code> </span> aObserver, in unsigned long aDelay, in unsigned long aType);</code></td>
+ </tr>
+ <tr>
+ <td><code>void <a href="/../../../../En/NsITimer#cancel.28.29" title="../../../../En/NsITimer#cancel.28.29">cancel</a>();</code></td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div id="section_2">
+ <h2 class="editable" id="属性"><span>属性</span></h2>
+ <div class="editIcon">
+ <a href="/../../../../En/NsITimer#" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="../../../../skins/common/icons/icon-trans.gif"></span></a></div>
+ <table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">Attribute</td>
+ <td class="header">Type</td>
+ <td class="header">Description</td>
+ </tr>
+ <tr>
+ <td><code>delay</code></td>
+ <td><code>unsigned long</code></td>
+ <td>The timeout delay in millisecond.</td>
+ </tr>
+ <tr>
+ <td><code>type</code></td>
+ <td><code>unsigned long</code></td>
+ <td>Defines the timer type: one shot, repeating slack or repeating precise. Must be one of the constants defined under <span class="lang lang-en"><a href="/../../../../En/NsITimer#Constants" title="../../../../En/NsITimer#Constants">Constants</a> </span> on this page</td>
+ </tr>
+ <tr>
+ <td><code>callback</code></td>
+ <td><code>readonly <span class="lang lang-en"><code><a href="../../../../en/nsITimerCallback" rel="internal">nsITimerCallback</a></code> </span> </code></td>
+ <td>The <code>nsITimerCallback</code> object passed to <code>initWithCallback()</code>.</td>
+ </tr>
+ <tr>
+ <td><code>closure</code></td>
+ <td><code>[noscript] readonly voidPtr</code></td>
+ <td>
+ <p>The opaque pointer pass to <code>initWithFuncCallback()</code>.</p>
+ </td>
+ </tr>
+ <tr>
+ <td>target</td>
+ <td><span class="lang lang-en"><code><a class="new" href="../../../../en/nsIEventTarget" rel="internal">nsIEventTarget</a></code> </span></td>
+ <td>The <span class="lang lang-en"><code><a class="new" href="../../../../en/nsIEventTarget" rel="internal">nsIEventTarget</a></code> </span> to which the callback is dispatched.  This target must be set before calling any of the initialization methods.</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div id="section_3">
+ <h2 class="editable" id="常量"><span>常量</span></h2>
+ <div class="editIcon">
+ <a href="/../../../../En/NsITimer#" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="../../../../skins/common/icons/icon-trans.gif"></span></a></div>
+ <table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">Constant</td>
+ <td class="header">Value</td>
+ <td class="header">Description</td>
+ </tr>
+ <tr>
+ <td><code>TYPE_ONE_SHOT</code></td>
+ <td>0</td>
+ <td>Type of a timer that fires once only.</td>
+ </tr>
+ <tr>
+ <td><code>TYPE_REPEATING_SLACK</code></td>
+ <td>1</td>
+ <td>After firing, the timer is stopped and not restarted until its callback completes. Specified timer period will be at least the time between when processing for last firing the callback completes and when the next firing occurs.</td>
+ </tr>
+ <tr>
+ <td><code>TYPE_REPEATING_PRECISE</code></td>
+ <td>2</td>
+ <td>This repeating timer aims to have constant period between firings. The processing time for each timer callback should not influence the timer period. However, if the processing for the last timer firing could not be completed until just before the next firing occurs, then you could have two timer notification routines being executed in quick succession.</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div id="section_4">
+ <h2 class="editable" id="方法"><span>方法</span></h2>
+ <div class="editIcon">
+ <a href="/../../../../En/NsITimer#" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="../../../../skins/common/icons/icon-trans.gif"></span></a></div>
+ <div id="section_5">
+ <h3 class="editable" id="initWithCallback()"><span>initWithCallback()</span></h3>
+ <div class="editIcon">
+ <a href="/../../../../En/NsITimer#" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="../../../../skins/common/icons/icon-trans.gif"></span></a></div>
+ <p>Initialize a timer to fire after the given millisecond interval. This version takes a function to call and a closure to pass to that function.</p>
+ <pre class="eval"> void initWithCallback (
+ in nsITimerCallback aCallback,
+ in unsigned long aDelay,
+ in unsigned long aType
+ );
+</pre>
+ <div id="section_6">
+ <h6 class="editable" id="Parameters"><span>Parameters</span></h6>
+ <div class="editIcon">
+ <a href="/../../../../En/NsITimer#" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="../../../../skins/common/icons/icon-trans.gif"></span></a></div>
+ <dl>
+ <dt>
+ <code>aFunc</code></dt>
+ <dd>
+ <span class="lang lang-en"><code><a href="../../../../en/nsITimerCallback" rel="internal">nsITimerCallback</a></code> </span> interface to call when timer expires.</dd>
+ </dl>
+ <dl>
+ <dt>
+ <code>aDelay</code></dt>
+ <dd>
+ timeout delay in milliseconds.</dd>
+ </dl>
+ <dl>
+ <dt>
+ <code>aType</code></dt>
+ <dd>
+ Defines the timer type: one shot, repeating slack or repeating precise. Must be one of the constants defined under <span class="lang lang-en"><a href="/../../../../En/NsITimer#Constants" title="../../../../En/NsITimer#Constants">Constants</a> </span> on this page.</dd>
+ </dl>
+ </div>
+ </div>
+ <div id="section_7">
+ <h3 class="editable" id="initWithFuncCallback()"><span>initWithFuncCallback()</span></h3>
+ <div class="editIcon">
+ <a href="/../../../../En/NsITimer#" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="../../../../skins/common/icons/icon-trans.gif"></span></a></div>
+ <p>Initialize a timer to fire after the given millisecond interval. This version takes a function to call and a closure to pass to that function.</p>
+ <pre class="eval"> [noscript] void initWithFuncCallback(
+ in nsTimerCallbackFunc aCallback,
+ in voidPtr aClosure,
+ in unsigned long aDelay,
+ in unsigned long aType
+ );
+</pre>
+ <div id="section_8">
+ <h6 class="editable" id="Parameters_2"><span>Parameters</span></h6>
+ <div class="editIcon">
+ <a href="/../../../../En/NsITimer#" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="../../../../skins/common/icons/icon-trans.gif"></span></a></div>
+ <dl>
+ <dt>
+ <code>aFunc</code></dt>
+ <dd>
+ a <span class="lang lang-en"><code><a class="new" href="../../../../en/nsITimerCallbackFunc" rel="internal">nsITimerCallbackFunc</a></code> </span> interface compatible function to call when timer fires.</dd>
+ </dl>
+ <dl>
+ <dt>
+ <code>aClosure</code></dt>
+ <dd>
+ An opaque pointer to pass to that function.</dd>
+ </dl>
+ <dl>
+ <dt>
+ <code>aDelay</code></dt>
+ <dd>
+ timeout delay in milliseconds.</dd>
+ </dl>
+ <dl>
+ <dt>
+ <code>aType</code></dt>
+ <dd>
+ Defines the timer type: one shot, repeating slack or repeating precise. Must be one of the constants defined under <span class="lang lang-en"><a href="/../../../../En/NsITimer#Constants" title="../../../../En/NsITimer#Constants">Constants</a> </span> on this page.</dd>
+ </dl>
+ </div>
+ </div>
+ <div id="section_9">
+ <h3 class="editable" id="init()"><span>init()</span></h3>
+ <div class="editIcon">
+ <a href="/../../../../En/NsITimer#" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="../../../../skins/common/icons/icon-trans.gif"></span></a></div>
+ <p>Initialize a timer that will fire after the specified delay. A user must keep a reference to this timer till it is no longer needed or has been canceled.</p>
+ <pre class="eval"> void init(
+ in nsIObserver aObserver,
+ in unsigned long aDelay,
+ in unsigned long aType
+ );
+</pre>
+ <div id="section_10">
+ <h6 class="editable" id="Parameters_3"><span>Parameters</span></h6>
+ <div class="editIcon">
+ <a href="/../../../../En/NsITimer#" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="../../../../skins/common/icons/icon-trans.gif"></span></a></div>
+ <dl>
+ <dt>
+ <code>aObserver</code></dt>
+ <dd>
+ A callback Object, that is capable listening to timer events. If the timer fires, the observer will be notified via the <span class="lang lang-en"><code><a href="../../../../en/nsIObserver" rel="internal">nsIObserver</a></code> </span> Interface. The subject is set to the <code>nsITimer</code> Object which fired, the topic is equal to "timer-callback" and data is always set to null.</dd>
+ </dl>
+ <dl>
+ <dt>
+ <code>aDelay</code></dt>
+ <dd>
+ timeout delay in milliseconds.</dd>
+ </dl>
+ <dl>
+ <dt>
+ <code>aType</code></dt>
+ <dd>
+ Defines the timer type: one shot, repeating slack or repeating precise. Must be one of the constants defined under <span class="lang lang-en"><a href="/../../../../En/NsITimer#Constants" title="../../../../En/NsITimer#Constants">Constants</a> </span> on this page.</dd>
+ </dl>
+ </div>
+ </div>
+ <div id="section_11">
+ <h3 class="editable" id="cancel()"><span>cancel()</span></h3>
+ <div class="editIcon">
+ <a href="/../../../../En/NsITimer#" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="../../../../skins/common/icons/icon-trans.gif"></span></a></div>
+ <p>Cancels the timer. This method works on all types, not just on repeating timers -- you might want to cancel a TYPE_ONE_SHOT timer, and even reuse it by re-initializing it (to avoid object destruction and creation costs by conserving one timer instance).</p>
+ <pre class="eval"> void cancel();
+</pre>
+ <div id="section_12">
+ <h6 class="editable" id="Parameters_4"><span>Parameters</span></h6>
+ <div class="editIcon">
+ <a href="/../../../../En/NsITimer#" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="../../../../skins/common/icons/icon-trans.gif"></span></a></div>
+ <p>None.</p>
+ </div>
+ </div>
+ </div>
+ <div id="section_13">
+ <h2 class="editable" id="备注"><span>备注</span></h2>
+ <div class="editIcon">
+ <a href="/../../../../En/NsITimer#" style="" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="../../../../skins/common/icons/icon-trans.gif"></span></a></div>
+ <p>TYPE_REPEATING_SLACK timer is the preferable repeating timer type for most situations<span id="1243145776531S" style="display: none;"> </span></p>
+ </div>
+ <div id="section_14">
+ <h2 class="editable" id="sect1"> </h2>
+ <div class="editIcon">
+ 实例</div>
+ <div class="editIcon">
+ <a href="/../../../../En/NsITimer#" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="../../../../skins/common/icons/icon-trans.gif"></span></a></div>
+ <pre class="eval"> // we need a <span class="lang lang-en"><code><a href="../../../../en/nsITimerCallback" rel="internal">nsITimerCallback</a></code>
+</span> compatible...
+ // ... interface for the callbacks.
+ var event
+ = { notify: function(timer) { alert("Fire!"); } }
+
+ // Now it is time to create the timer...
+ var timer
+ = Components.classes["@mozilla.org/timer;1"]
+ .createInstance(Components.interfaces.nsITimer);
+
+ // ... and to initialize it, we want to call event.notify() ...
+ // ... one time after exactly ten second.
+ timer.initWithCallback(
+ event,
+ 10000,
+ Components.interfaces.nsITimer.TYPE_ONE_SHOT);
+</pre>
+ <p> </p>
+ </div>
+ <div id="section_15">
+ <h2 class="editable" id="请参阅"><span>请参阅</span></h2>
+ <div class="editIcon">
+ <a href="/../../../../En/NsITimer#" title="Edit section"><span class="icon"><img alt="Edit section" class="sectionedit" src="../../../../skins/common/icons/icon-trans.gif"></span></a></div>
+ <p><span class="lang lang-en"><code><a class="new" href="../../../../en/nsITimerCallbackFunc" rel="internal">nsITimerCallbackFunc</a></code> </span>, <span class="lang lang-en"><code><a href="../../../../en/nsITimerCallback" rel="internal">nsITimerCallback</a></code></span></p>
+ </div>
+ </div>
+</div>
+
+<p><strong class="tag-label">标记:</strong></p>
+<div id="pageTags">
+ <div class="pageTagList">
+ <div class="item taglist">
+ <a href="/../../../../Special:Tags?tag=Interfaces&amp;language=en" title="Interfaces">Interfaces</a>, <a href="/../../../../Special:Tags?tag=Interfaces:Scriptable&amp;language=en" title="Interfaces:Scriptable">Interfaces:Scriptable</a>, <a href="/../../../../Special:Tags?tag=XPCOM&amp;language=en" title="XPCOM">XPCOM</a>, <a href="/../../../../Special:Tags?tag=XPCOM+API+Reference&amp;language=en" title="XPCOM API Reference">XPCOM API Reference</a></div>
+ </div>
+</div>
+<p> </p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsitraceablechannel/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsitraceablechannel/index.html
new file mode 100644
index 0000000000..ce7c6deb2f
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsitraceablechannel/index.html
@@ -0,0 +1,71 @@
+---
+title: nsITraceableChannel
+slug: Mozilla/Tech/XPCOM/Reference/Interface/NsITraceableChannel
+translation_of: Mozilla/Tech/XPCOM/Reference/Interface/NsITraceableChannel
+---
+<p></p><div style="border: solid #ddd 2px; margin-bottom: 12px;">
+<div style="background: #eee; padding: 2px;"><code><a href="https://dxr.mozilla.org/mozilla-central/source/netwerk/base/public/nsITraceableChannel.idl" rel="custom">netwerk/base/public/nsITraceableChannel.idl</a></code><span style="text-align: right; float: right;"><a href="/zh-CN/docs/Interfaces/About_Scriptable_Interfaces" style="color: #00cc00; font-weight: 700;">脚本化</a></span></div>
+<span style="padding: 4px 2px;">这个接口用于允许拦截 <a href="/en-US/docs/HTTP" title="/en-US/docs/HTTP">HTTP</a> 流量。It is implemented by <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIHttpChannel" title="">nsIHttpChannel</a></code>.</span>
+
+ <div style="height: 42px; position: relative; padding: 2px; width: auto;">
+
+ <div style="top: 22px; font-size: 11px; position: absolute;">1.0</div>
+
+ <div style="top: 22px; font-size: 11px; position: absolute; left: 0px; text-align: right; float: right; width: 100%;">66</div>
+
+ <div style="height: 8px; top: 16px; background: #dd0000; left: 0px; position: absolute; width: 8.952380571428572%;"></div>
+
+<div style="height: 8px; top: 16px; left: 8.952380571428572%; background: #00dd00; position: absolute; width: 91.04761942857142%;" title="Introduced in Gecko 1.9.0.4 "></div>
+
+<div style="top: 0px; font-size: 11px; position: absolute; left: 8.952380571428572%;">Introduced</div>
+<div style="top: 22px; font-size: 11px; position: absolute; left: 8.952380571428572%;">Gecko 1.9.0.4</div>
+
+</div>
+
+<div style="background: #eee; padding: 2px;">
+继承于: <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupports" title="">nsISupports</a></code>
+<span style="text-align: right; float: right;">最后修改于Gecko 1.9.0.4 </span></div>
+</div><p></p>
+<p>使用这个接口的典型方式如下:</p>
+<ul>
+ <li><a href="/en/XUL_School/Intercepting_Page_Loads#HTTP_Observers" title="en/XUL_School/Intercepting_Page_Loads#HTTP_Observers">注册“http-on-examine-response”通知</a>来跟综全部 HTTP 响应;</li>
+ <li>跳过重定义 (<code>responseStatus</code> = 3xx on <a href="/en-US/docs/XPCOM_Interface_Reference/nsIHttpChannel" title="/en-US/docs/XPCOM_Interface_Reference/nsIHttpChannel">nsIHttpChannel</a>),否则你可能<a class="link-https" href="https://bugzilla.mozilla.org/show_bug.cgi?id=728901#c8" title="https://bugzilla.mozilla.org/show_bug.cgi?id=728901#c8">最终有两个监听视(listeners)注册通道(channel)</a>;</li>
+ <li>QI the channel passed as the "<code>subject</code>" to your observer to <code>nsITraceableChannel</code>, and replace the default <code>nsIStreamListener</code> (that passes the data to the original requester - e.g. to XMLHttpRequest or to the browser tab that made the request) with your own implementation (see <a href="#Using_channel_listeners" title="#Using_channel_listeners">"Implementing nsIStreamListener"</a> below).</li>
+</ul>
+<p>之后,你的 nsIStreamListener 实现将会获取到响应数据(response data),并且能够传递数据到原始的 nsIStreamListener(可能会修改它)。</p>
+<p>See <a class="external" href="http://www.softwareishard.com/blog/firebug/nsitraceablechannel-intercept-http-traffic/" title="http://www.softwareishard.com/blog/firebug/nsitraceablechannel-intercept-http-traffic/">nsITraceableChannel, Intercept HTTP Traffic</a> for a more detailed description with code samples.</p>
+<p>See <a href="http://stackoverflow.com/questions/5205672/modify-url-before-loading-page-in-firefox/" title="http://stackoverflow.com/questions/5205672/modify-url-before-loading-page-in-firefox/"> Modify URL before loading page in firefox</a> for an overview of how to <strong>modify</strong> a request before it is made.</p>
+<h2 id="Method_overview" name="Method_overview">Method overview</h2>
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>nsIStreamListener <a href="#setNewListener()">setNewListener</a>(in nsIStreamListener aListener);</code></td>
+ </tr>
+ </tbody>
+</table>
+<h2 id="Methods" name="Methods">Methods</h2>
+<h3 id="setNewListener()" name="setNewListener()">setNewListener()</h3>
+<p>用一个新的来替换该通道的当前监听器,返回先前分配给该通道的监听器。</p>
+<pre class="eval">nsIStreamListener setNewListener(
+ in nsIStreamListener aListener
+);
+</pre>
+<h6 id="Parameters" name="Parameters">参数</h6>
+<dl>
+ <dt>
+ <code>aListener</code></dt>
+ <dd>
+ An <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIStreamListener" title="">nsIStreamListener</a></code> to be notified of events on the HTTP channel.</dd>
+</dl>
+<h6 id="Return_value" name="Return_value">返回值</h6>
+<p>该通道的前一个监听器。Each listener call through to the previous listener for every call, in order to establish a call chain to allow all interested parties a chance to act on each event.</p>
+<h2 id="Using_channel_listeners" name="Using_channel_listeners">实现 nsIStreamListener</h2>
+<p>一个 <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIStreamListener" title="">nsIStreamListener</a></code> 接口传递给 <code>setNewListener()</code> 需要实现下列的方法,这是通过调用(这些方法)来通知它在 HTTP stream 上发生的事件:</p>
+<ul>
+ <li><code>onStartRequest</code>:一个 HTTP 请求开始。</li>
+ <li><code>onDataAvailable:</code>数据到达 HTTP 通道(HTTP channel)。</li>
+ <li><code>onStopRequest</code>:HTTP 请求结束。</li>
+</ul>
+<div class="note">
+ <strong>Note:</strong> It is critical that you pass along requests to the previous listener as soon as possible -- especially for <code>onStartRequest</code>.</div>
+<p>Channels may restrict when you may replace the listener. In particular, listeners typically should not be replaced after <code>onStartRequest</code> has been called.</p>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiuri/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiuri/index.html
new file mode 100644
index 0000000000..d133861ac3
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsiuri/index.html
@@ -0,0 +1,407 @@
+---
+title: nsIURI
+slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIURI
+translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIURI
+---
+<p></p><div style="border: solid #ddd 2px; margin-bottom: 12px;">
+<div style="background: #eee; padding: 2px;"><code><a href="https://dxr.mozilla.org/mozilla-central/source/netwerk/base/public/nsIURI.idl" rel="custom">netwerk/base/public/nsIURI.idl</a></code><span style="text-align: right; float: right;"><a href="/zh-CN/docs/Interfaces/About_Scriptable_Interfaces" style="color: #00cc00; font-weight: 700;">脚本化</a></span></div>
+<span style="padding: 4px 2px;">
+
+这是具有国际化支持的统一资源标识符的接口,提供允许设置和查询URI基本组件的属性以及用于在URI上执行基本操作的方法。
+</span>
+
+<div style="background: #eee; padding: 2px;">
+继承于: <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsISupports" title="">nsISupports</a></code>
+<span style="text-align: right; float: right;">最后修改于Gecko 6.0 (Firefox 6.0 / Thunderbird 6.0 / SeaMonkey 2.3)</span></div>
+</div><p></p>
+
+<p>细节请查看下列 RFCs:</p>
+
+<ul>
+ <li><a class="external" href="http://www.ietf.org/rfc/rfc3490.txt" title="http://www.ietf.org/rfc/rfc3490.txt">RFC3490</a>: 在应用程序中的国际域名 (IDNA)</li>
+ <li><a class="external" href="http://tools.ietf.org/rfc/rfc3986.txt" title="http://tools.ietf.org/rfc/rfc3986.txt">RFC3986</a>: 统一资源标识符 (URI): 通用词法</li>
+ <li><a class="external" href="http://tools.ietf.org/rfc/rfc3987.txt" title="http://tools.ietf.org/rfc/rfc3987.txt">RFC3987</a>: 国际化的内容标识</li>
+</ul>
+
+<p><code>nsIURI</code>的子类,  例如 <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIURL" title="">nsIURL</a></code>, 加强了URI未来的结构化.</p>
+
+<p>为了创建一个 <code>nsIURI</code> 对象, 你应该如此使用 <code><a href="https://developer.mozilla.org/zh-CN/docs/XPCOM_Interface_Reference/nsIIOService#newURI()">nsIIOService.newURI()</a></code>:</p>
+
+<pre class="brush: js">function makeURI(aURL, aOriginCharset, aBaseURI) {
+ var ioService = Components.classes["@mozilla.org/network/io-service;1"]
+ .getService(Components.interfaces.nsIIOService);
+ return ioService.newURI(aURL, aOriginCharset, aBaseURI);
+}
+</pre>
+
+<h2 id="Components_of_a_URI" name="Components_of_a_URI">一个 URI 的组件</h2>
+
+<table class="standard-table">
+ <thead>
+ <tr>
+ <th colspan="7" scope="col" style="text-align: center;">prePath</th>
+ <th colspan="2" scope="col" style="text-align: center;">path</th>
+ </tr>
+ <tr>
+ <th scope="col" style="text-align: center;">scheme</th>
+ <th scope="col" style="text-align: center;"> </th>
+ <th scope="col" style="text-align: center;">userPass</th>
+ <th scope="col" style="text-align: center;"> </th>
+ <th scope="col" style="text-align: center;">host</th>
+ <th scope="col" style="text-align: center;"> </th>
+ <th scope="col" style="text-align: center;">port</th>
+ <th scope="col" style="text-align: center;"> </th>
+ <th scope="col" style="text-align: center;">ref</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td style="text-align: right;">ftp</td>
+ <td>://</td>
+ <td>username@password</td>
+ <td>@</td>
+ <td>hostname</td>
+ <td>:</td>
+ <td>portnumber</td>
+ <td>/pathname?query=value</td>
+ <td>#ref</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Method_overview" name="Method_overview">函数预览</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td><code>nsIURI <a href="#clone()">clone</a>();</code></td>
+ </tr>
+ <tr>
+ <td><code>nsIURI <a href="#cloneIgnoringRef()">cloneIgnoringRef</a>();</code> </td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#equals()">equals</a>(in nsIURI other);</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#equalsExceptRef()">equalsExceptRef</a>(in nsIURI other);</code> </td>
+ </tr>
+ <tr>
+ <td><code>AUTF8String <a href="#resolve()">resolve</a>(in AUTF8String relativePath);</code></td>
+ </tr>
+ <tr>
+ <td><code>boolean <a href="#schemeIs()">schemeIs</a>(in string scheme);</code></td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Attributes" name="Attributes">属性</h2>
+
+<table class="standard-table">
+ <tbody>
+ <tr>
+ <td class="header">属性</td>
+ <td class="header">类别</td>
+ <td class="header">描述</td>
+ </tr>
+ <tr>
+ <td><code>asciiHost</code></td>
+ <td><code><a href="/en/ACString" title="en/ACString">ACString</a></code></td>
+ <td>
+ <p>The URI <code>host</code> with an ASCII compatible encoding. Follows the IDNA draft specification for converting internationalized domain names (UTF-8) to ASCII for compatibility with existing Internet infrastructure. <strong>Read only.</strong></p>
+
+ <div class="note">
+ <p><strong>Note:</strong> IPv6 addresses are not enclosed in square brackets.</p>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td><code>asciiSpec</code></td>
+ <td><code><a href="/en/ACString" title="en/ACString">ACString</a> (US-ASCII)</code></td>
+ <td>The URI spec with an ASCII compatible encoding. The host portion follows the IDNA draft spec. Other parts are URL-escaped per the rules of <a class="external" href="http://tools.ietf.org/rfc/rfc3986.txt" title="http://tools.ietf.org/rfc/rfc3986.txt">RFC3986</a>. The result is strictly ASCII. <strong>Read only.</strong></td>
+ </tr>
+ <tr>
+ <td><code>hasRef</code></td>
+ <td><code>boolean</code></td>
+ <td>Returns if there is a reference portion (the part after the "#") of the URI.<br>
+ <br>
+ </td>
+ </tr>
+ <tr>
+ <td><code>host</code></td>
+ <td><code><a href="/en/AUTF8String" title="en/AUTF8String">AUTF8String</a></code></td>
+ <td>
+ <p>The host is the Internet domain name to which this URI refers. It could be an IPv4 (or IPv6) address literal. If supported, it could be a non-ASCII internationalized domain name.</p>
+
+ <h6 id="Exceptions_thrown">Exceptions thrown</h6>
+
+ <dl>
+ <dt><code>NS_ERROR_FAILURE</code></dt>
+ <dd>If host is not applicable to the URI scheme (e.g. about:blank)</dd>
+ </dl>
+
+ <div class="note"><strong>Note:</strong> Characters are <strong>not</strong> escaped. IPv6 addresses are not enclosed in square brackets.</div>
+ </td>
+ </tr>
+ <tr>
+ <td><code>hostPort</code></td>
+ <td><code><a href="/en/AUTF8String" title="en/AUTF8String">AUTF8String</a></code></td>
+ <td>
+ <p>The "host:port" part of the URI (or simply the host, if port is -1).</p>
+
+ <h6 id="Exceptions_thrown_2">Exceptions thrown</h6>
+
+ <dl>
+ <dt><code>NS_ERROR_FAILURE</code></dt>
+ <dd>If hostPort is not applicable to the URI scheme (e.g. about:blank)</dd>
+ </dl>
+
+ <div class="note"><strong>Note:</strong> Characters are <strong>not</strong> escaped.</div>
+ </td>
+ </tr>
+ <tr>
+ <td><code>originCharset</code></td>
+ <td><code><a href="/en/ACString" title="en/ACString">ACString</a></code></td>
+ <td>
+ <p>The charset of the document from which this URI originated. An empty value implies UTF-8.</p>
+ If this value is something other than UTF-8 then the URI components (for example <code>spec</code>, <code>prePath</code>, <code>username</code>, and so on) are all fully URL-escaped. Otherwise, the URI components may contain unescaped multibyte UTF-8 characters. <strong>Read only.</strong></td>
+ </tr>
+ <tr>
+ <td><code>password</code></td>
+ <td><code><a href="/en/AUTF8String" title="en/AUTF8String">AUTF8String</a></code></td>
+ <td>
+ <p>The optional password, assuming the <code>preHost</code> consists of "username:password".</p>
+
+ <h6 id="Exceptions_thrown_3">Exceptions thrown</h6>
+
+ <dl>
+ <dt><code>NS_ERROR_FAILURE</code></dt>
+ <dd>If password is not applicable to the URI scheme (e.g. about:blank)</dd>
+ </dl>
+
+ <p></p><div class="blockIndicator note"><strong>Note:</strong> Some characters may be escaped.</div><p></p>
+ </td>
+ </tr>
+ <tr>
+ <td><code>path</code></td>
+ <td><code><a href="/en/AUTF8String" title="en/AUTF8String">AUTF8String</a></code></td>
+ <td>
+ <p>The path, typically including at least a leading '/' (but may also be empty, depending on the protocol).</p>
+ <div class="blockIndicator note"><strong>Note:</strong> Some characters may be escaped.</div></td>
+ </tr>
+ <tr>
+ <td><code>port</code></td>
+ <td><code><a href="/en/long" title="en/long">long</a></code></td>
+ <td>
+ <p>The URI's port. A port value of -1 corresponds to the protocol's default port (for example -1 implies port 80 for HTTP URIs).</p>
+
+ <h6 id="Exceptions_thrown_4">Exceptions thrown</h6>
+
+ <dl>
+ <dt><code>NS_ERROR_FAILURE</code></dt>
+ <dd>If port is not applicable to the URI scheme (e.g. about:blank)</dd>
+ </dl>
+ </td>
+ </tr>
+ <tr>
+ <td><code>prePath</code></td>
+ <td><code><a href="/en/AUTF8String" title="en/AUTF8String">AUTF8String</a></code></td>
+ <td>
+ <p>The <code>prePath</code> returns the string before the path (such as "<a class="external" rel="freelink">scheme://user:password@host</a>:port").</p>
+
+ <p>This is related to the <a class="external" href="http://tools.ietf.org/html/rfc6454" title="http://tools.ietf.org/html/rfc6454">Web Origin Concept of RFC6454</a>.</p>
+
+ <p>This is useful for authentication, managing sessions, or for checking the <code>origin</code> of an URI to prevent cross-site scripting attacks while using methods such as <a href="/zh-CN/docs/Web/API/Window/postMessage" title="window.postMessage() 方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议(通常为https),端口号(443为https的默认值),以及主机  (两个页面的模数 Document.domain设置为相同的值) 时,这两个脚本才能相互通信。window.postMessage() 方法提供了一种受控机制来规避此限制,只要正确的使用,这种方法就很安全。"><code>window.postMessage()</code></a>.</p>
+ <div class="blockIndicator note"><strong>Note:</strong> Some characters may be escaped.</div> <strong>Read only.</strong></td>
+ </tr>
+ <tr>
+ <td><code>ref</code></td>
+ <td><code><a href="/en/AUTF8String" title="en/AUTF8String">AUTF8String</a></code></td>
+ <td>
+ <p>Returns the reference portion (the part after the "#") of the URI. If there is not one, an empty string is returned.</p>
+ <div class="blockIndicator note"><strong>Note:</strong> Some characters may be escaped.</div> </td>
+ </tr>
+ <tr>
+ <td><code>scheme</code></td>
+ <td><code><a href="/en/ACString" title="en/ACString">ACString</a> (US-ASCII)</code></td>
+ <td>
+ <p>The <code>scheme</code> is the protocol to which this URI refers. The scheme is restricted to the US-ASCII charset per <a class="external" href="http://tools.ietf.org/rfc/rfc3986.txt" title="http://tools.ietf.org/rfc/rfc3986.txt">RFC3986</a>.</p>
+
+ <div class="warning"><strong>Warning:</strong> Setting this is highly discouraged outside of a protocol handler implementation, since doing so will generally lead to unpredictable results.</div>
+ </td>
+ </tr>
+ <tr>
+ <td><code>spec</code></td>
+ <td><code><a href="/en/AUTF8String" title="en/AUTF8String">AUTF8String</a></code></td>
+ <td>
+ <p>Returns a string representation of the URI. Setting the <code>spec</code> causes the new spec to be parsed using the rules for the scheme the URI currently has. If the string cannot be parsed as a URI, <code>NS_ERROR_MALFORMED_URI</code> thrown.</p>
+
+ <div class="warning"><strong>Warning:</strong> Because parsing the string is done using the current URI's scheme, setting the spec to a URI with a different scheme will produce incorrect results. Therefore, only protocol handler implementations should do this.</div>
+
+ <p>If the URI stores information from the <code><a href="/zh-CN/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIIOService" title="">nsIIOService</a></code> interface's <code><a href="https://developer.mozilla.org/zh-CN/docs/XPCOM_Interface_Reference/nsIIOService#newURI()">nsIIOService.newURI()</a></code> call that created it, other than just the parsed string, the behavior of this information when setting the <code>spec</code> attribute is undefined.</p>
+ <div class="blockIndicator note"><strong>Note:</strong> Some characters may be escaped.</div></td>
+ </tr>
+ <tr>
+ <td><code>specIgnoringRef</code></td>
+ <td><code><a href="/en/AUTF8String" title="en/AUTF8String">AUTF8String</a></code></td>
+ <td>Returns a string representation of the URI without the <code>ref</code> (part after the #) portion.<br>
+ <br>
+ <div class="blockIndicator note"><strong>Note:</strong> Some characters may be escaped.</div> </td>
+ </tr>
+ <tr>
+ <td><code>username</code></td>
+ <td><code><a href="/en/AUTF8String" title="en/AUTF8String">AUTF8String</a></code></td>
+ <td>
+ <p>The optional username, assuming the <code>preHost</code> consists of "username:password".</p>
+
+ <h6 id="Exceptions_thrown_5">Exceptions thrown</h6>
+
+ <dl>
+ <dt><code>NS_ERROR_FAILURE</code></dt>
+ <dd>If username is not applicable to the URI scheme (e.g. about:blank)</dd>
+ </dl>
+ <div class="blockIndicator note"><strong>Note:</strong> Some characters may be escaped.</div></td>
+ </tr>
+ <tr>
+ <td><code>userPass</code></td>
+ <td><code><a href="/en/AUTF8String" title="en/AUTF8String">AUTF8String</a></code></td>
+ <td>
+ <p>The "username:password" (or username only if the value doesn't contain a ':').</p>
+
+ <h6 id="Exceptions_thrown_6">Exceptions thrown</h6>
+
+ <dl>
+ <dt><code>NS_ERROR_FAILURE</code></dt>
+ <dd>If userPass is not applicable to the URI scheme (e.g. about:blank)</dd>
+ </dl>
+ <div class="blockIndicator note"><strong>Note:</strong> Some characters may be escaped.</div></td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Methods" name="Methods">Methods</h2>
+
+<h3 id="clone()" name="clone()">clone()</h3>
+
+<p>Clones the URI, returning a new <code>nsIURI</code> object.</p>
+
+<div class="note"><strong>Note:</strong> For some protocols, this is more than just an optimization. For example, under Mac OS X, the spec of a file URI doesn't necessarily uniquely identify a file, since two volumes can have the same name.</div>
+
+<pre class="eval">nsIURI clone();
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<p>None.</p>
+
+<h6 id="Return_value" name="Return_value">Return value</h6>
+
+<p>An <code>nsIURI</code> object that represents the same URI as the current <code>nsIURI</code>.</p>
+
+<p></p><h3 id="cloneIgnoringRef()">cloneIgnoringRef()</h3><p></p>
+
+<p>Clones the current URI, clearing the <code>'ref'</code> attribute in the clone.</p>
+
+<pre class="eval">nsIURI cloneIgnoringRef();
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<p>None.</p>
+
+<h6 id="Return_value" name="Return_value">Return value</h6>
+
+<p>An <code>nsIURI</code> object that represents the same URI as the current <code>nsIURI</code> without the <code>'ref'</code> attribute.</p>
+
+<h3 id="equals()" name="equals()">equals()</h3>
+
+<p>Compares the current URI with another URI.</p>
+
+<div class="note"><strong>Note:</strong> This is more than a string comparison, as two different URI strings can represent the same location. For example, comparing "<a class="external" href="http://foo.com:80/" rel="freelink">http://foo.com:80/</a>" and "<a class="external" href="http://foo.com/" rel="freelink">http://foo.com/</a>" will return <code>true</code>.</div>
+
+<pre class="eval">boolean equals(
+ in nsIURI other
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<dl>
+ <dt><code>other</code></dt>
+ <dd>Another <code>nsIURI</code> to compare to.</dd>
+</dl>
+
+<h6 id="Return_value" name="Return_value">Return value</h6>
+
+<p><code>true</code> if the two URIs represent the same location; otherwise <code>false</code>.</p>
+
+<p></p><h3 id="equalsExceptRef()">equalsExceptRef()</h3><p></p>
+
+<p>Compares the current URI with another URI, ignoring the value of the <code>.ref</code> member.</p>
+
+<div class="note"><strong>Note:</strong> This is more than a string comparison, as two different URI strings can represent the same location. For example, comparing "<a class="external" href="http://foo.com/#" rel="freelink">http://foo.com/#</a>" and "<a class="external" href="http://foo.com/" rel="freelink">http://foo.com/</a>" or "<a class="external" href="http://foo.com/#aaa" rel="freelink">http://foo.com/#aaa</a>" and "<a class="external" href="http://foo.com/#bbb" rel="freelink">http://foo.com/#bbb</a>" will return <code>true</code>.</div>
+
+<pre class="eval">boolean equalsExceptRef(
+ in nsIURI other
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<dl>
+ <dt><code>other</code></dt>
+ <dd>Another <code>nsIURI</code> to compare to.</dd>
+</dl>
+
+<h6 id="Return_value" name="Return_value">Return value</h6>
+
+<p><code>true</code> if the two URIs represent the same location; otherwise <code>false</code>.</p>
+
+<h3 id="resolve()" name="resolve()">resolve()</h3>
+
+<p>Resolves a relative URI string, using this URI as the base.</p>
+
+<p></p><div class="blockIndicator note"><strong>Note:</strong> Some implementations may have no concept of a relative URI.</div><p></p>
+
+<pre class="eval">AUTF8String resolve(
+ in AUTF8String relativePath
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<dl>
+ <dt><code>relativePath</code></dt>
+ <dd>The relative path to resolve.</dd>
+</dl>
+
+<h6 id="Return_value" name="Return_value">Return value</h6>
+
+<p>The resolved absolute URI string.</p>
+
+<h3 id="schemeIs()" name="schemeIs()">schemeIs()</h3>
+
+<p>Quickly reports whether the <code>nsIURI</code> represents a URI with the specified scheme. This comparison is case-insensitive.</p>
+
+<p></p><div class="blockIndicator note"><strong>Note:</strong> This is an optimization, allowing you to check the scheme of the URI without having to get the scheme and do the comparison yourself; this saves memory allocations.</div><p></p>
+
+<pre class="eval">boolean schemeIs(
+ in string scheme
+);
+</pre>
+
+<h6 id="Parameters" name="Parameters">Parameters</h6>
+
+<dl>
+ <dt><code>scheme</code></dt>
+ <dd>A string representing the scheme to compare to.</dd>
+</dl>
+
+<h6 id="Return_value" name="Return_value">Return value</h6>
+
+<p><code>true</code> if the URI is for the specified scheme; otherwise <code>false</code>.</p>
+
+<h2 id="See_also" name="See_also">See also</h2>
+
+<ul>
+ <li><a href="/en/Code_snippets/URI_parsing" title="en/Code_snippets/URI_parsing">Code snippets:URI parsing</a></li>
+</ul>
diff --git a/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsixmlhttprequest/index.html b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsixmlhttprequest/index.html
new file mode 100644
index 0000000000..f12f52cb12
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/reference/interface/nsixmlhttprequest/index.html
@@ -0,0 +1,90 @@
+---
+title: nsIXMLHttpRequest
+slug: Mozilla/Tech/XPCOM/Reference/Interface/nsIXMLHttpRequest
+tags:
+ - XMLHttpRequest
+ - XPCOM API 参考
+ - XPCOM 接口参考
+ - 指南
+ - 接口
+translation_of: Mozilla/Tech/XPCOM/Reference/Interface/nsIXMLHttpRequest
+---
+<div class="blockIndicator obsolete obsoleteHeader"><p><strong><span class="icon-only-inline" title="This is an obsolete API and is no longer guaranteed to work."><i class="icon-trash"> </i></span> Obsolete since Gecko 60 (Firefox 60 / Thunderbird 60 / SeaMonkey 2.57)</strong><br>This feature is obsolete. Although it may still work in some browsers, its use is discouraged since it could be removed at any time. Try to avoid using it.</p></div>
+
+<p><code>nsIXMLHttpRequest</code> along with <code><a href="/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIJSXMLHttpRequest" title="">nsIJSXMLHttpRequest</a></code> and <code><a href="/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIXMLHttpRequestEventTarget" title="">nsIXMLHttpRequestEventTarget</a></code> are Mozilla's implementation details of the DOM <a href="/en/DOM/XMLHttpRequest" title="en/DOM/XMLHttpRequest">XMLHttpRequest</a> object.</p>
+
+<div class="note"><strong>注意:</strong> 如果你是 Web 开发者或者 Mozilla add-on 开发者,请参考 <a href="/en/DOM/XMLHttpRequest">XMLHttpRequest</a>。</div>
+
+<p>This page contains documentation, specific to Mozilla application and add-on developers.</p>
+
+<p>The interface definition: <a href="https://dxr.mozilla.org/mozilla-central/source/dom/xhr/nsIXMLHttpRequest.idl">https://dxr.mozilla.org/mozilla-central/source/dom/xhr/nsIXMLHttpRequest.idl</a></p>
+
+<h3 id="Elevated_Privileges">Elevated Privileges</h3>
+
+<p>As mentioned in the "Non-Standard Properties" the property of <code>channel</code> was read-only. When using the XPCOM interface, as seen below in <a href="#Example_code">Example 2</a>, we can get access to this. The most obvious benefit is that we can set <a href="/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/NsIRequest#Constants">nsiRequest - Constants</a> in the <code>xhr.channel.loadFlags</code>. For instance, as done in <a href="#Example_code">Example 2</a>, the flag of <code>LOAD_ANONYMOUS</code> is added, this strips all user data (cookies, tokens, etc).</p>
+
+<h3 id="Using_event_handlers_from_native_code">Using event handlers from native code</h3>
+
+<p>(Not sure if it's up-to-date)</p>
+
+<p>From native code, the way to set up onload and onerror handlers is a bit different. Here is a comment from Johnny Stenback &lt;<a class="link-mailto" href="mailto:jst@netscape.com" rel="freelink">jst@netscape.com</a>&gt;:</p>
+
+<blockquote>The mozilla implementation of nsIXMLHttpRequest implements the interface nsIDOMEventTarget and that's how you're supported to add event listeners. Try something like this: nsCOMPtr&lt;nsIDOMEventTarget&gt; target(do_QueryInterface(myxmlhttpreq)); target-&gt;AddEventListener(NS_LITERAL_STRING("load"), mylistener, PR_FALSE) where mylistener is your event listener object that implements the interface nsIDOMEventListener. The 'onload', 'onerror', and 'onreadystatechange' attributes moved to nsIJSXMLHttpRequest, but if you're coding in C++ you should avoid using those.</blockquote>
+
+<p>Though actually, if you use addEventListener from C++ weird things will happen too, since the result will depend on what JS happens to be on the stack when you do it....</p>
+
+<p>Conclusion: Do not use event listeners on XMLHttpRequest from C++, unless you're aware of all the security implications. And then think twice about it.</p>
+
+<h2 id="Example_code" name="Example_code">Example code</h2>
+
+<p>This is a simple example code for opening a simple HTTP request from a xul application (like a Mozilla extension) without using observers:</p>
+
+<pre class="eval"> var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance();
+ req.open('POST', "<a class="external" href="http://www.foo.bar:8080/nietzsche.do" rel="freelink">http://www.foo.bar:8080/nietzsche.do</a>", true);
+ req.send('your=data&amp;and=more&amp;stuff=here');
+</pre>
+
+<h2 id="Example_code" name="Example_code">Example 2</h2>
+
+<pre><code>var {Cu: utils, Cc: classes, Ci: instances} = Components;
+Cu.import('resource://gre/modules/Services.jsm');
+function xhr(url, cb) {
+ let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
+
+ let handler = ev =&gt; {
+ evf(m =&gt; xhr.removeEventListener(m, handler, !1));
+ switch (ev.type) {
+ case 'load':
+ if (xhr.status == 200) {
+ cb(xhr.response);
+ break;
+ }
+ default:
+ Services.prompt.alert(null, 'XHR Error', 'Error Fetching Package: ' + xhr.statusText + ' [' + ev.type + ':' + xhr.status + ']');
+ break;
+ }
+ };
+
+ let evf = f =&gt; ['load', 'error', 'abort'].forEach(f);
+ evf(m =&gt; xhr.addEventListener(m, handler, false));
+
+ xhr.mozBackgroundRequest = true;
+ xhr.open('GET', url, true);
+ xhr.channel.loadFlags |= Ci.nsIRequest.LOAD_ANONYMOUS | Ci.nsIRequest.LOAD_BYPASS_CACHE | Ci.nsIRequest.INHIBIT_PERSISTENT_CACHING;
+ xhr.responseType = "arraybuffer"; //dont set it, so it returns string, you dont want arraybuffer. you only want this if your url is to a zip file or some file you want to download and make a nsIArrayBufferInputStream out of it or something
+ xhr.send(null);
+}
+
+xhr('https://www.gravatar.com/avatar/eb9895ade1bd6627e054429d1e18b576?s=24&amp;d=identicon&amp;r=PG&amp;f=1', data =&gt; {
+ Services.prompt.alert(null, 'XHR Success', data);
+ var file = OS.Path.join(OS.Constants.Path.desktopDir, "test.png");
+ var promised = OS.File.writeAtomic(file, new UInt8Array(data));
+ promised.then(
+ function() {
+ alert('succesfully saved image to desktop')
+ },
+ function(ex) {
+ alert('FAILED in saving image to desktop')
+ }
+ );
+});</code></pre>
diff --git a/files/zh-cn/mozilla/tech/xpcom/setting_http_request_headers/index.html b/files/zh-cn/mozilla/tech/xpcom/setting_http_request_headers/index.html
new file mode 100644
index 0000000000..b91030b424
--- /dev/null
+++ b/files/zh-cn/mozilla/tech/xpcom/setting_http_request_headers/index.html
@@ -0,0 +1,261 @@
+---
+title: Setting HTTP request headers
+slug: Mozilla/Tech/XPCOM/Setting_HTTP_request_headers
+translation_of: Mozilla/Tech/XPCOM/Setting_HTTP_request_headers
+---
+<p><a href="https://developer.mozilla.org/en-US/docs/HTTP">HTTP</a> 是网络背后的核心技术之一。除了实质内容之外,一些重要的信息通过HTTP 头传递给HTTP 请求和响应。</p>
+
+<p>你可以添加你自己的HTTP头到应用程序所做的任何请求中,不论你的代码是否启动了显式打开了基于 <a href="/zh-cn/nsIXMLHttpRequest" title="zh-cn/XMLHttpRequest">XMLHttpRequest</a> 活动、&lt;img&gt;元素或者甚至是从css中的 HTTP Channel的请求。</p>
+
+<h3 id="HTTP_Channels">HTTP Channels</h3>
+
+<p>当你处理HTTP请求和响应时,通常情况下你是通过 <code><a href="/zh-cn/XPCOM_Interface_Reference/nsIHttpChannel" title="zh-cn/XPCOM_Interface_Reference/nsIHttpChannel">nsIHttpChannel</a></code>来做的。 <code><a href="/zh-cn/XPCOM_Interface_Reference/nsIHttpChannel" title="zh-cn/XPCOM_Interface_Reference/nsIHttpChannel">nsIHttpChannel</a></code>接口有一些属性和方法,但是这下方法中我们只对<code>setRequestHeader感兴趣。这个方法允许我们设置一个</code> <em>HTTP request header</em>.</p>
+
+<p>下面是设置一个HTTP header 的简单代码</p>
+
+<pre class="eval">// adds "X-Hello: World" header to the request
+httpChannel.setRequestHeader("X-Hello", "World", false);
+</pre>
+
+<p>在这个示例代码中我们有一个变量名为httpChannel,它是一个nsIHttpChannel的实例。</p>
+
+<p>setRequestHeader有三个参数,第一个参数是HTTP请求头的名字,第二个参数是HTTP请求头的值,第三个参数我们暂时忽略它,总设置其为false。</p>
+
+<p>在我们的示例代码中,我们为HTTP reques header中增加了被我们命名为X-Hello的HTTP请求头,其值为World</p>
+
+<div class="note">
+<p><s><strong>NOTE</strong>: If you are making up your own HTTP header, you MUST put a <code>X-</code> in front of the name. (In our example, our made up HTTP header is <code>X-Hello</code> and NOT <code>Hello</code> because we correctly added the <code>X-</code> in front of our name.)</s></p>
+
+<p><br>
+ <strong>No longer the case: <a class="external" href="http://tools.ietf.org/html/draft-ietf-appsawg-xdash-02" title="http://tools.ietf.org/html/draft-ietf-appsawg-xdash-02">http://tools.ietf.org/html/draft-ietf-appsawg-xdash-02</a></strong></p>
+</div>
+
+<h3 id="Notifications" name="Notifications">Notifications</h3>
+
+<p>The question that may be coming to your mind right now is, how do you get the <code>nsIHttpChannel</code> when an HTTP request is made.</p>
+
+<p>In the case your code initiates the request, you probably already have one. Trapping other requests is done with notifications, which are a lot like <em>events</em> or <em>signals</em> found in other languages and frameworks.</p>
+
+<p>In particular, to get the <code>nsIHttpChannel</code> just before the HTTP request is made we need to <em>observe</em> the <code>"http-on-modify-request"</code> topic. (And yes, <code>"http-on-modify-request"</code> is a string.)</p>
+
+<div class="note">
+<p><strong>NOTE</strong>: There are many topics, besides just <code>"http-on-modify-request"</code>, that you can get notifications about, for example <code>"http-on-examine-response"</code> and <code>"xpcom-shutdown"</code>. You can also make up your own topics and send out your own notifications.</p>
+
+<p>For more information about notifications framework and a list of common notification topics, see <a href="/zh-cn/Observer_Notifications" title="zh-cn/Observer_Notifications">Observer Notifications</a>.</p>
+</div>
+
+<h3 id="Observers" name="Observers">Observers</h3>
+
+<p>To get notified about some topic (like <code>"http-on-modify-request"</code>) we need to create an <strong>observer</strong>. An observer is a component implementing <a href="/zh-cn/XPCOM_Interface_Reference/nsIObserver" title="zh-cn/nsIObserver">nsIObserver</a> interface. And once the observer is <em>registered</em> for a topic, it will get notified about the topic by having its <code>observe</code> method called.</p>
+
+<p>Below is an example observer that adds a custom header "X-Hello" to the channel passed in for http-on-modify-request notification:</p>
+
+<pre class="brush: js">var httpRequestObserver =
+{
+ observe: function(subject, topic, data)
+ {
+ if (topic == "http-on-modify-request") {
+ var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);
+ httpChannel.setRequestHeader("X-Hello", "World", false);
+ }
+ }
+};
+</pre>
+
+<p><span class="comment">div class="note"&gt; Doesn't seem very suitable for this article; readers should are typically assumed to be familiar with JS. Nickolay '''NOTE''': Often people expect <a href="/zh-cn/JavaScript" title="zh-cn/JavaScript">JavaScript</a> to be just like <a href="/zh-cn/Java" title="zh-cn/Java">Java</a>. And while superficially, they look very similar, there are some important differences between the two. For example, while Java is an &lt;em&gt;object-oriented programming language&lt;/em&gt;, JavaScript is not. JavaScript is &lt;em&gt;prototype-based programming language&lt;/em&gt; and as such while it has &lt;em&gt;objects&lt;/em&gt; it does not have &lt;em&gt;classes&lt;/em&gt;. (Which is why, if you are not well versed with JavaScript, the object creation in the sample code above may look strange.) &lt;/div</span></p>
+
+<p>Note that the number of parameter that the <code>observe</code> method takes is important. It takes 3 parameters (as we've shown in the example code above). For the <code>"http-on-modify-request"</code> topic, the first parameter (named <code>subject</code> in the code above) will be the <code>nsIHttpChannel</code>. However, it is passed to us as an <code><a href="/zh-cn/XPCOM_Interface_Reference/nsISupports" title="zh-cn/nsISupports">nsISupports</a></code>. So we need to <em>change</em> the <code>nsISupports</code> into a <code>nsIHttpChannel</code> which is what the <code>QueryInterface</code> call does. And yes, <em>converting</em> objects from one kind to another is very ugly, and lacks (what is usually called) <em>syntactic sugar</em>.</p>
+
+<p>The second line of code in the <code>if</code> block should already be familiar to you. It is the same code we used before, earlier in this article, to add the HTTP request header.</p>
+
+<p>The name of this object -- <code>httpRequestObserver</code> -- isn't important. We could have named it anything we liked.</p>
+
+<h3 id="Registering" name="Registering">Registering</h3>
+
+<p>After we've created the observer, we need to register it. In our case, we want to register it for the <code>"http-on-modify-request"</code> topic. We can do this with the code below.</p>
+
+<pre class="eval">var observerService = Components.classes["@<a class="linkification-ext external" href="http://mozilla.org/observer-service;1" title="Linkification: http://mozilla.org/observer-service;1">mozilla.org/observer-service;1</a>"]
+ .getService(Components.interfaces.<a href="/zh-cn/XPCOM_Interface_Reference/nsIObserverService" title="zh-cn/XPCOM_Interface_Reference/nsIObserverService">nsIObserverService</a>);
+observerService.addObserver(httpRequestObserver, "http-on-modify-request", false);
+</pre>
+
+<p>The first statement gets the object that will let us register with topics that we want to get notified about.</p>
+
+<p>The second statement does the actual registering. We are saying we want <code>httpRequestObserver</code> to be notified (by calling its <code>observe</code> method) when a <code>"http-on-modify-request"</code> topic takes place (which we know happens just before each HTTP request).</p>
+
+<h3 id="Unregistering" name="Unregistering">Unregistering</h3>
+
+<p>You should unregister the observer on shutdown. Failing to do that may cause memory leaks. To unregister the observer use <code>nsIObserverService.removeObserver</code> as follows:</p>
+
+<pre class="eval">observerService.removeObserver(httpRequestObserver, "http-on-modify-request");</pre>
+
+<h3 id="All-in-one_example">All-in-one example</h3>
+
+<p>Here is a slightly different version of our <code>httpRequestObserver</code> object. While the previous version we showed before was good for learning, in an actual real-world application, you'd probably want to code it more like the following.</p>
+
+<pre class="brush: js">var httpRequestObserver =
+{
+ observe: function(subject, topic, data)
+ {
+ if (topic == "http-on-modify-request") {
+ var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);
+ httpChannel.setRequestHeader("X-Hello", "World", false);
+ }
+ },
+
+ get observerService() {
+ return Components.classes["@<a class="linkification-ext" href="http://mozilla.org/observer-service;1" title="Linkification: http://mozilla.org/observer-service;1">mozilla.org/observer-service;1</a>"]
+ .getService(Components.interfaces.nsIObserverService);
+ },
+
+ register: function()
+ {
+ this.observerService.addObserver(this, "http-on-modify-request", false);
+ },
+
+ unregister: function()
+ {
+ this.observerService.removeObserver(this, "http-on-modify-request");
+ }
+};
+</pre>
+
+<p>This object has a convenience <code>register()</code> and <code>unregister()</code> methods, so in order to activate it you just need to call:</p>
+
+<pre class="eval">httpRequestObserver.register();
+</pre>
+
+<p>You should also remember to unregister the observer at shutdown:</p>
+
+<pre class="eval">httpRequestObserver.unregister();
+</pre>
+
+<p>And that's it.</p>
+
+<h3 id="XPCOM_components" name="XPCOM_components">XPCOM components</h3>
+
+<p>You need to register a single <code>http-on-modify-request</code> observer per application (and not one per window). This means that you should put the observer's implementation in an <a href="/zh-cn/How_to_Build_an_XPCOM_Component_in_Javascript" title="zh-cn/How_to_Build_an_XPCOM_Component_in_Javascript">XPCOM component</a> instead of an <a href="/zh-cn/XUL_Overlays" title="zh-cn/XUL_Overlays">overlay</a>. If you want to support Gecko2 (Firefox4) you need to register your javascript component as described here: <a class="linkification-ext" href="/zh-cn/XPCOM/XPCOM_changes_in_Gecko_2.0#JavaScript_components" title="Linkification: https://developer.mozilla.org/zh-cn/XPCOM/XPCOM_changes_in_Gecko_2.0#JavaScript_components">https://developer.mozilla.org/zh-cn/XPCOM/XPCOM_changes_in_Gecko_2.0#JavaScript_components</a>.</p>
+
+<pre class="brush: js">var headerName = "X-hello";
+var headerValue = "world";
+
+function LOG(text)
+{
+ // var consoleService = Components.classes["@<a class="linkification-ext" href="http://mozilla.org/consoleservice;1" title="Linkification: http://mozilla.org/consoleservice;1">mozilla.org/consoleservice;1</a>"].getService(Components.interfaces.nsIConsoleService);
+ // consoleService.logStringMessage(text);
+}
+
+function myHTTPListener() { }
+
+myHTTPListener.prototype = {
+
+ observe: function(subject, topic, data)
+ {
+ if (topic == "http-on-modify-request") {
+
+ LOG("----------------------------&gt; (" + subject + ") mod request");
+
+ var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);
+ httpChannel.setRequestHeader(headerName, headerValue, false);
+ return;
+ }
+
+
+ if (topic == "profile-after-change") {
+
+ LOG("----------------------------&gt; profile-after-change");
+
+ var os = Components.classes["@<a class="linkification-ext" href="http://mozilla.org/observer-service;1" title="Linkification: http://mozilla.org/observer-service;1">mozilla.org/observer-service;1</a>"]
+ .getService(Components.interfaces.nsIObserverService);
+
+ os.addObserver(this, "http-on-modify-request", false);
+ return;
+ }
+ },
+
+ QueryInterface: function (iid) {
+ if (iid.equals(Components.interfaces.nsIObserver) ||
+ iid.equals(Components.interfaces.nsISupports))
+ return this;
+
+ Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE;
+ return null;
+ },
+};
+
+var myModule = {
+ registerSelf: function (compMgr, fileSpec, location, type) {
+
+ var compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
+ compMgr.registerFactoryLocation(this.myCID,
+ this.myName,
+ this.myProgID,
+ fileSpec,
+ location,
+ type);
+
+
+ LOG("----------------------------&gt; registerSelf");
+
+ var catMgr = Components.classes["@<a class="linkification-ext" href="http://mozilla.org/categorymanager;1" title="Linkification: http://mozilla.org/categorymanager;1">mozilla.org/categorymanager;1</a>"].getService(Components.interfaces.nsICategoryManager);
+ catMgr.addCategoryEntry("app-startup", this.myName, this.myProgID, true, true);
+ },
+
+
+ getClassObject: function (compMgr, cid, iid) {
+
+ LOG("----------------------------&gt; getClassObject");
+
+ return this.myFactory;
+ },
+
+ myCID: Components.ID("{9cf5f3df-2505-42dd-9094-c1631bd1be1c}"),
+
+ myProgID: "@dougt/myHTTPListener;1",
+
+ myName: "Simple HTTP Listener",
+
+ myFactory: {
+ QueryInterface: function (aIID) {
+ if (!aIID.equals(Components.interfaces.nsISupports) &amp;&amp;
+  !aIID.equals(Components.interfaces.nsIFactory))
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ return this;
+ },
+
+ createInstance: function (outer, iid) {
+
+ LOG("----------------------------&gt; createInstance");
+
+ return new myHTTPListener();
+ }
+ },
+
+ canUnload: function(compMgr) {
+ return true;
+ }
+};
+
+function NSGetModule(compMgr, fileSpec) {
+ return myModule;
+}
+</pre>
+
+<h3 id="Privacy_and_security_good_practice">Privacy and security good practice</h3>
+
+<p>A use case for setting specific a HTTP request header is to have a specific web site be able to check if a specific plugin / addon / extension is installed.</p>
+
+<p>The good practice is not to have this specific HTTP header (<code>for example </code>"X-site.net-extension") sent all the time but only when doing requests with this specific web sites. By not advertising to all sites what extensions are installed this improves both privacy (this makes it harder to track a user known by his set of plugins, addons and extensions) and security (some plugins, addons and extensions may be known to have flaws by attackers).</p>
+
+<p>With this privacy and security addition the code to use becomes:</p>
+
+<pre class="brush: js"> observe: function(subject, topic, data)
+ {
+ if (topic == "http-on-modify-request") {
+ var httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel);
+<code> if (/site.net/.test(</code>httpChannel<code>.originalURI.host)) {
+</code> httpChannel.setRequestHeader("X-Hello", "World", false);
+ }
+ }
+ },
+</pre>