aboutsummaryrefslogtreecommitdiff
path: root/files/ko/gecko_embedding_basics/index.html
blob: 1626e6db7979ae88d677bd4396f295bed2b192df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
---
title: Gecko Embedding Basics
slug: Gecko_Embedding_Basics
tags:
  - Embedding Mozilla
translation_of: Mozilla/Gecko/Gecko_Embedding_Basics
---
<p>정보의 원천, 놀이, 개인간 교류 수단으로써 웹의 중요성이 끝없이 증가하면서, HTML 포맷으로 저장된 데이터에 접근하고 보는 능력은 다양한 소프트웨어 애플리케이션을 폭넓게 대체하기 위해 점점 더 중요해지고 있다. 단순한 HTML 페이지 뷰어건 완벽한 기능의 웹 브라우저이건, HTML 기반 문서를 해석하고 그려내는 것은 수많은 상황에서 매우 중요한 기능이 됐다. 애플리케이션 개발자는 개발 시간을 최소화하면서도 애자일하고 안정성이 높은 제품을 만들기 위해, HTML을 출력하는 결정적인 기능을 어떻게 구현할지에 고민하게 되었다. Gecko, 즉 넷스케이프와 모질라 브라우저의 핵심에 있는 렌더링 엔진을 임베딩하는 것은 이런 문제에 대한 훌륭한 해결책이다.</p>

<h2 id=".EC.99.9C_Gecko.EC.9D.B8.EA.B0.80.3F" name=".EC.99.9C_Gecko.EC.9D.B8.EA.B0.80.3F">왜 Gecko인가?</h2>

<p>Gecko를 임베딩하는 것은 현명한 선택이다. Gecko는 빠르고, 안정적이며 표준을 매우 잘 지키고 있다. Mozilla와 Netscape의 지원 아래서 매우 널리 배포되었으며 많은 사람들이 꾸준히 지켜보고 있다.</p>

<p>Gecko는 오픈 소스이다. 다른 임베딩 브라우저 솔루션과는 달리, Gecko의 모든 소스 코드는 자유롭게 사용할 수 있으며 마음껏 수정할 수 있다. 필요한 만큼 뜯어 고칠 수 있다. 또한 현재의 라이센스에 따르면, Gecko를 독점적인 상용 제품에 컴포넌트로 사용할 수도 있다.</p>

<p>Gecko는 Mozilla 프로젝트와 연관되어 있으므로, Mozilla 프로젝트에서 임베딩 작업에 도움이 되는 많은 리소스를 쉽게 얻을 수 있다. Mozilla <a class="external" href="http://www.mozilla.org">웹 사이트</a>에는 <a class="external" href="http://mozilla.org/projects/embedding/">임베딩 프로젝트 영역</a>이 있다. 또한 mozilla.dev.emobedding 뉴스그룹이 있으며, 많은 관련 뉴스그룹과 함께 임베딩 개발자들 간에 정보를 교환하는 것을 주 목적으로 하고 있다. 전체 <a class="external" href="http://lxr.mozilla.org/seamonkey">코드기반 상호 참조</a>가 가능하며, <a class="external" href="http://bugzilla.mozilla.org/">Bugzilla 버그 데이터베이스</a>를 통해 버그 제출, 버그 진행 상황 참조, 버그 수정 참여 등을 간단히 할 수 있다.</p>

<p>Gecko는 바닥부터 크로스플랫폼으로 설계되었다. mozill.org에서는 직접 Wintel, MacOS 9.0과 OS X, 리눅스를 지원하고 있으며, 수많은 다른 플랫폼도 써드파티에서 지원하고 있다.</p>

<p>마지막으로, Gecko를 라이센스하는 것은 로열티가 필요 없으며, 심지어 독점 저작권을 갖는 상용 제품에도 로열티없이 적용할 수 있다. "매우" 일반적으로는, 모질라가 제공하는 원본 소스코드에 대해서는 어떤 수정도 커뮤니티에 반환되어야 한다.(Gecko를 임베드하는 코드까지 반환해야하는 것은 아니다.) 즉 애플리케이션의 사용자라면 사용중인 Gecko 엔진에 해당하는 소스 코드를 언제든지 얻을 수 있어야 하며(대부분 mozilla.org 웹사이트 링크를 통해서), 애플리케이션은 명확한 방법으로 Gecko를 사용하고 있음을 공지해야 한다. (예를 들면, 제품 박스 위의 로고나 About: 페이지 등) 가능한 라이센스 방법에 대한 정확한 설명은 라이센스에 대해 유일한 법적 근거인 <a class="external" href="http://www.mozill.org/MPL/">Mozilla &amp; Nescape Public Licneses</a>에서 볼 수 있다.</p>

<h2 id=".EC.9E.84.EB.B2.A0.EB.94.A9.EC.97.90_.ED.95.84.EC.9A.94.ED.95.9C_.EA.B2.83" name=".EC.9E.84.EB.B2.A0.EB.94.A9.EC.97.90_.ED.95.84.EC.9A.94.ED.95.9C_.EA.B2.83">임베딩에 필요한 것</h2>

<p>Gecko를 임베드하기로 결정했다면, 세가지 과정을 밟아야 한다. 첫째로 코드를 얻는다. 다음으로 Gecko 코드베이스를 다루는데 사용되는 몇가지 지정 기술을 이해해야 한다. 마지막으로 추가하려는 부가적인 기능을 결정해야 한다. 이 절은 이러한 과정을 안내할 것이다.</p>

<h3 id=".EC.BD.94.EB.93.9C_.EC.96.BB.EA.B8.B0" name=".EC.BD.94.EB.93.9C_.EC.96.BB.EA.B8.B0">코드 얻기</h3>

<p>이 글을 쓰는 시점에서 Gecko를 임베드하기 위한 파일을 얻는 가장 좋은 방법은 전체 Mozill 소스 트리를 다운로드해서 빌드하는 것이다. 사실 상당히 간단한 과정이다. 전체 설명과 적절한 링크는 <a href="ko/Download_Mozilla_Source_Code">Download Mozilla Source Code</a>에서 찾을 수 있다. 두번째 방법(컴포넌트에 의한 컴포넌트)은 현재 개발 중이며, 아직 베타 상태에 있다. 이 프로젝트에 대한 정보는 <a class="external" href="http://www.mozilla.org/projects/embedding/bootstrap.html">REQUIRES 기반 빌드 메카니즘</a>에서 찾을 수 있다. 그 외에, Gecko 런타임 환경(<a href="ko/GRE">GRE</a>, Gecko Runtime Environment)가 개발중에 있다. <a href="ko/GRE">GRE</a>는 단일 코어 라이브러리를 사용하는 모질라 컴포넌트 위에서 여러가지 애플리케이션을 지원하기 위한 것이다. (컴포넌트에 의한 컴포넌트를 사용하려고 생각한다면, 우선 버전과 바이너리 호환성에 대한 이슈를 잘 살펴봐야 한다. <a class="external" href="http://mozilla.org/projects/xpcom/glue/Component_Reuse.html">XPCOM 컴포넌트 재사용</a>을 살펴보면 도움이 될 것이다.)</p>

<p>우선 몇가지 도구(기본으로 컴파일러, 펄 배포판, 몇몇 범용 유틸리티)를 가져와야 한다. 그런 다음 컴퓨터 환경을 설정하고, 소스를 다운로드 한다. 전체 트리를 다운로드하려 한다면, 두가지 방법이 있다. FTP에서 전체 소스 트리를 tar로 압축한 파일을 가져올 수 있다. (이것이 가장 간단한 방법이며, 확실히 컴파일이 가능한 한 방법이다. 다만 최근에 수정된 코드는 포함하지 않았을 수도 있다.) 다른 방법은 CVS에서 가장 최신의 코드를 가져오거나 변경분에 대한 업데이트를 수행하는 것이다. 소스를 가져와서 환경 설정을 적절히 끝마친 다음에는 제공된 makfile 중 적절한 것을 실행하면 된다. 각 플랫폼마다 컴파일 과정에 대한 상세한 설명이 있다.</p>

<p>빌드가 끝나면 mozilla/embedding/config 디렉토리로 간다. 거기서 예제 manifest 파일을 찾을 수 있을 것이다. (파일들은 모두 이름이 "basebrowser"로 시작한다. manifest 파일은 각 플래폼마다 임베딩을 위한 개별 설정이다. 기본으로 들어있는 것은 단지 예제일 뿐이며, 당신의 목적에는 딱 들어맞지 않을 수도 있다. 하지만 예제로 시작해서 조금씩 수정해 나가면 좋을 것이다. 각 플랫폼마다 모델로 삼을 만한 예제 임베딩 프로젝트들도 있다. <a href="ko/Roll_your_own_browser_-_An_embedding_HowTo">Roll_your_own_browser_-_An_embedding_HowTo</a>를 참고하라.</p>

<h3 id=".EC.BD.94.EB.93.9C_.EC.9E.91.EC.84.B1_.ED.99.98.EA.B2.BD_.EC.9D.B4.ED.95.B4.ED.95.98.EA.B8.B0" name=".EC.BD.94.EB.93.9C_.EC.9E.91.EC.84.B1_.ED.99.98.EA.B2.BD_.EC.9D.B4.ED.95.B4.ED.95.98.EA.B8.B0">코드 작성 환경 이해하기</h3>

<p>모질라는 처음부터 여러 플랫폼과 프로그래밍 언어에 대한 설계와 개발을 지원하는 것으로 시작됐다. 결국 여러가지 자체 프로그래밍 기술이 개발되었으며, 모두 다 객체 은폐라는 이상적인 개념을 바탕으로 두고 있다. Gecko 임베딩에는 XPCOM, XPIDL, XPConnect, 특별 문자열 클래스, XUL 등의 기술에 대한 실제적인 지식을 필요로 한다. 다음은 각 기술에 대한 간략한 소개이다. 더 자세한 정보는 mozilla.org 사이트에서 찾을 수 있다.</p>

<h4 id="XPCOM" name="XPCOM">XPCOM</h4>

<p>모질라 기술 중 가장 중요한 것은 <a href="ko/XPCOM">XPCOM</a>, 즉 크로스플랫폼 컴포넌트 오브젝트 모델(Cross-Platform Component Object Model)이다. XPCOM은 객체나 다른 데이터의 생성, 소유, 제거를 모질라 전체에 걸쳐 관리하는 프레임워크를 제공한다. MSCOM을 사용한 적이 있다면, 기본적으로 유사한 개념임을 느낄 것이다. 하지만 매우 큰 차이가 있다. XPCOM은 크로스플랫폼이며 단일 스레드에서 대부분 동작하도록 설계되어 있다. 또한 XPCOM와 MSCOM은 현재로써는 아직 호환되지 않는다.</p>

<h5 id=".EC.9D.B8.ED.84.B0.ED.8E.98.EC.9D.B4.EC.8A.A4" name=".EC.9D.B8.ED.84.B0.ED.8E.98.EC.9D.B4.EC.8A.A4">인터페이스</h5>

<p>XPCOM의 핵심은 인터페이스라는 개념이다. 인터페이스는 특정 기증과 연관된 메소드, 속성, 관련 상수의 집합을 기술한 것일 뿐이다. 실제 기능을 구현하는 클래스와는 전혀 별개이다. 인터페이스는 계약의 역할을 한다. 특정 인터페이스를 지원하는 객체는 인터페이스에 기술된 서비스를 수행한다는 약속의 의미이다. 인터페이스를 최대한 중립적으로 유지할 수 있도록 IDL(Interface Definition Language)라는 별도의 언어를 사용해서 기술한다. 인터페이스 파일은 일반적으로 .idl이라는 확장자를 갖는다. 인터페이스의 기능을 지정할 뿐만 아니라 인터페이스의 IID도 지정한다. IID는 인터페이스를 지정할 때 사용하는 세계에서 유일한 번호이다.</p>

<p>Gecko 내에서 이루어지는 통신의 대부분은 추상 구조체를 거친다. (규약에 따라 추상 구조체의 이름은 <code>nsISomething</code>의 형식을 따른다.)</p>

<pre>//이거야
void ProcessSample(nsISample* aSample) {
	aSample-&gt;Poke("Hello");
//이건 아니야
void ProcessSample(nsSampleImpl* aSample) {
	aSample-&gt;Poke("hello");
</pre>

<h5 id=".40status_FROZEN" name=".40status_FROZEN">@status FROZEN</h5>

<p>XPCOM의 추상화 수준으로 인해 시스템이 매우 큰 유연성을 갖추게 됐다. 구현은 필요에 따라 얼마든지 변경할 수 있다. 하지만 최소한 인터페이스 자체는 고정된 채로 유지해야 한다. 모질라의 초기 설계와 개발 기간 동안에는 인터페이스는 다소 유동적인 것이었지만, 프로젝트가 성숙되면서 점점 더 많은 인터페이스가 FROZEN으로 표시됐다. FROZEN으로 표시된 인터페이스는 향후 변경되지 않음을 보장한다는 의미이다.</p>

<p>임베딩 관련된 대부분의 주요 인터페이스가 FROZEN으로 표시되긴 했지만, 인터페이스를 사용하기 전에 확인해보는 것이 좋다. 인터페이스의 상태는 .idl 파일의 주석에 나열된다. 얼려진 인터페이스(frozen interface)는 <code>@status FROZEN</code>라는 표시가 달린다. 모질라 상호 참조 도구를 사용해서 <a class="external" href="http://lxr.mozilla.org/seamonkey/search?string=%40status+FROZEN">얼려진 인터페이스를 검색</a>할 수도 있다. 얼려지지 않은 상태의 인터페이스는 언제든지 변경될 가능성이 있다. 얼리는 과정에 대한 자세한 정보는 <a class="external" href="http://mozilla.org/embedding/">임베딩 프로젝트 페이지</a>를 참고하라.</p>

<p>인터페이스가 얼려지고 나면 해당 인터페이스는 <a class="external" href="http://mozilla.org/projects/embedding/embedapiref/embedapi.html">Gecko 임베딩 API 참조</a>에 추가된다.</p>

<h5 id="nsISupports" name="nsISupports">nsISupports</h5>

<p>한 객체가 하나 이상의 인터페이스를 지원할 수 있다. 실제로는 모든 객체는 최소한 두 개의 인터페이스를 지원해야 한다. 하나는 실제 객체의 역할이 되는 무언가이고, 다른 하나는 범용적인 목적으로 사용되는 <code>nsISupports</code>이다. 다르게 말하자면 <code>nsISupports</code>는 모든 XPCOM 인터페이스의 조상이다. 모든 인터페이스는 <code>nsISupports</code>로부터 상속되며, 대부분은 직접 상속받는다. <code>nsISupports</code>는 두가지 주요 기능을 갖는다. 런타임 타입 발견과 객체 생명주기 관리이다. MSCOM의 IUnknown과 동일한 역할을 한다.</p>

<p>모든 객체가 다중 인터페이스를 지원하기 때문에, 한 인터페이스에 대한 포인터를 가진 상태에서 해당 객체가 당장 필요한 기능을 제공하는 다른 인터페이스를 지원하는지 알아낼 수 있다. 첫번째 <code>nsISupports</code> 메소드인 <code>QueryInterface()</code>는 다음과 같은 질문을 수행한다. "나는 이 객체가 A 타입임(인터페이스 A를 지원함)을 알고 있다. 그런데 타입 B이기도 한가?(인터페이스 B도 지원하는가?)"</p>

<p>만일 그렇다면 <code>QueryInterface()</code>는 새로 요청된 인터페이스로 연결된 포인터를 반환한다.</p>

<pre>void ProcessSample(nsISample* aSample) {
	nsIExample *example;
	nsresult rv;
	rv = aSample-&gt;QueryInterface(NS_GET_IID(nsIExample),(void **)&amp;example);
	if (NS_SUCCEEDED(rv)) {
		example-&gt;DoSomeOperation();
		NS_RELEASE(example); // Release호출을 위해 매크로를 사용
	}
}
</pre>

<p>XPCOM은 간접적인 방법(컴포넌트 관리자)을 사용해서 객체의 인스턴스를 생성하기 때문에, 같은 객체에 대한 다중 포인터(각각 다양한 인터페이스로 연결됨)가 존재할 수 있으며, 포인터가 가리키는 모든 객체를 호출자가 정확하게 추적하기 어려워질 수 있다. 객체가 필요하지 않은 상황에서도 남아있게 되서 메모리 누수가 발생하거나, 필요한 객체가 삭제되는 바람에 댕글링 포인터가 나타날 수도 있다. <code>nsISupports</code>의 다른 두 메소드 <code>AddRef()</code><code>Release()</code>는 이런 이슈를 다루기 위해 설계된 것이다. 포인터가 변수에 입력될 때마다<code>AddRef()</code>가 호출되어 내부 카운터가 증가한다. 포인터가 풀려날 때마다 <code>Release()</code>가 호출되어 내부 카운터가 감소한다. 카운터가 0이 되면, 객체에 대한 포인터가 없으며 객체를 안전하게 삭제할 수 있다. 객체의 수명에 대한 제어는 객체 내부에 있는 것이다. 이와 같은 과정을 자동화할 수 있도록 돕는 유틸리티인 XPCOM "스마트" 포인터<a href="#nsCOMPtr">nsCOMPtr</a>에 대한 정보를 참고하라.</p>

<h5 id=".EA.B0.9D.EC.B2.B4_.EC.83.9D.EC.84.B1" name=".EA.B0.9D.EC.B2.B4_.EC.83.9D.EC.84.B1">객체 생성</h5>

<p>XPCOM에서는 객체의 인스턴스 생성조차도 간접적인 절차를 거친다. 인터페이스가 GUID(Globally Unique ID)인 IID를 갖는 것처럼, XPCOM 클래스도 자신만의 GUID인 CID를 갖는다. 또는 문자 기반 ID인 Contract ID로 참조하기도 한다. 두가지 ID 중 하나를 객체를 생성하는 영속적인 XPCOM 컴포넌트인 "컴포넌트 관리자"의 메소드에 전달한다. 새로운 클래스 라이브러리(XPCOM에서는 모듈이라고 부른다)를 시스템에 처음 배치할 때, 라이브러리는 자기 자신을 컴포넌트 관리자에 등록하며, 컴포넌트 관리자는 클래스(ID로 참조)와 클래스가 포함된 라이브러리를 매핑하는 레지스트리를 관리한다.</p>

<p>싱글턴 객체가 제공하는 몇가지 영속적인 서비스는 컴포넌트 관리자와 함께 서비스 관리자가 생성하고 제어한다. 컴포넌트 관리자 자체도 영속적인 서비스의 예시 중 하나이다.</p>

<h5 id=".EC.9A.94.EC.95.BD" name=".EC.9A.94.EC.95.BD">요약</h5>

<p>XPCOM에 포함된 기능은 추상 인터페이스로 기술되며, 시스템 요소 간의 대부분의 통신은 인터페이스를 거쳐서 이루어진다. 반면, 인터페이스를 구현하는 하부 객체들은 교차색인 레지스트리에 기반한 컴포넌트 관리자에 의해 간접적으로 생성된다.</p>

<p>모든 인터페이스가 공유하는 기능 한가지는 런타임에서 하부 객체에게 어떤 다른 인터페이스를 구현하고 있는지 질의하는 기능이다. 인터페이스는 고정되어 변하지 않는다는 가정이 있는 것이지만, 현재 모질라 코드베이스에서는 <code>FROZEN</code>으로 선언된 인터페이스들만이 크게 변경되지 않을 것임을 보장한다. 객체 생명주기 관리는 객체 내에 들어있는 자신에게로 향하는 포인터의 개수를 추적하는 내부 카운터를 통해 이루어진다. 객체를 사용하는 클라이언트가 해야 할 일은 카운터를 올리거나 내리는 것 뿐이다. 내부 카운터가 0에 도달하면 객체는 자기자신을 삭제한다.</p>

<h5 id="nsCOMPtr" name="nsCOMPtr">nsCOMPtr</h5>

<p>하지만 <code>AddRef()</code><code>Release()</code>를 적절한 때에 호출하는 것을 가끔 잊어버릴 수도 있다. 이런 과정을 더 쉽고 확실히 화기 위해 XPCOM은 내장 "스마트" 포인터인 <code>nsCOMPtr</code>을 제공한다. 이 포인터는 <code>AddRef()</code><code>Release()</code> 호출을 처리한다. 대신 <code>nsCOMPtr</code>을 사용하면 코드를 더 명확하고 효율적으로 만들 수 있다. 스마트 포인터에 대한 추가 정보는 "<a class="external" href="http://www.mozilla.org/projects/xpcom/nsCOMPtr.html">The Complete nsCOMPtr User's Manual</a>"을 참고하라.</p>

<p>모질라는 수많은 내장 매크로(규약에 따라 코드 내에서 모두 대문자로 작성됨)나 <code>nsCOMPtr</code>과 같은 유틸리티를 제공해서 XPCOM으로 코딩하는 과정을 더 쉽게 만들어 준다. 이들 중 대부분은 다음 파일에서 찾을 수 있다.</p>

<p>&lt;tt&gt;nsCom.h&lt;/tt&gt;, &lt;tt&gt;nsDebug.h&lt;/tt&gt;, &lt;tt&gt;nsError.h&lt;/tt&gt;, &lt;tt&gt;nsIServiceManager.h&lt;/tt&gt;, &lt;tt&gt;nsISupportsUtils.h&lt;/tt&gt;</p>

<p>모질라는 메모리 사용량 추적 기능 같은 개발 도구까지 제공한다. 이런 도구에 대한 정보는 <a class="external" href="http://www.mozilla.org/performance/" rel="freelink">http://www.mozilla.org/performance/</a> 에서 찾을 수 있다.</p>

<h5 id=".EC.B0.B8.EA.B3.A0.EC.9E.90.EB.A3.8C" name=".EC.B0.B8.EA.B3.A0.EC.9E.90.EB.A3.8C">참고자료</h5>

<p>XPCOM에 대한 참고자료는 일반적으로 <a href="ko/XPCOM">XPCOM</a>에서 찾을 수 있다. XPCOM 컴포넌트 작성에 대한 개략적인 내용은 오릴리 서적인<em><a class="external" href="http://books.mozdev.org/chapters/ch08.html">Creating Applications with Mozilla</a></em>의 8장에서 참고할 수 있다. 전체 내용이 XPCOM 관련된 책인<em><a href="ko/Creating_XPCOM_Components">Creating XPCOM Components</a></em>도 있다. Don Box가 저술한<em>Essential COM</em>에서는 COM 시스템의 기반 로직에 대해 더욱 상세히 설명하고 있다. 비록 MSCOM에 대해 초점을 맞춘 책이긴 하지만, 객체 모델 등을 사용할 때 필요한 핵심 원리를 이해하하기에 매우 훌륭한 배경지식을 제공한다.</p>

<h4 id="XPIDL" name="XPIDL">XPIDL</h4>

<p>인터페이스는 XPIDL(Cross Platform Interface Definition Language)로 작성된 추상 클래스이다. 여전히 인터페이스에서 제공할 기능은 몇몇 정규 프로그래밍 언어로 작성하는 것이 유용하다. XPIDL 컴파일러가 이런 역할을 한다. 인터페이스를 .idl 파일에 정의하면 XPIDL 컴파일러가 정의된 인터페이스를 처리한다.</p>

<p>컴파일러는 여러가지 출력이 가능하지만, 일반적으로는 두가지 출력을 사용한다. 인터페이스의 C++ 구현을 위해 사용하며 주석달린 템플릿을 포함하는 C++ .h 파일이 그 중 하나이다. 다른 하나는 XPConnect가 사용할 타입 라이브러리 정보를 포함하는 XPT 파일이다. XPConnect는 JavaScript에서 인터페이스를 사용할 수 있도록 한다. <a href="ko/XPIDL">XPIDL</a>의 문법(간단한 C 스타일 언어)에 대한 자료와 <a href="ko/XPIDL/xpidl">컴파일러</a> 사용법이 참고하라.</p>

<h4 id="XPConnect.EC.99.80_XPT_.ED.8C.8C.EC.9D.BC" name="XPConnect.EC.99.80_XPT_.ED.8C.8C.EC.9D.BC"><a href="ko/XPConnect">XPConnect</a>와 XPT 파일</h4>

<p><a href="ko/XPConnect">XPConnect</a><a href="ko/JavaScript">JavaScript</a>로 작성된 코드에 접근하거나, C++로 작성된 XPCOM 컴포넌트를 다룰 수 있도록 하는 <a href="ko/XPCOM">XPCOM</a> 모듈이다. XPConnect를 사용하면, XPCOM 인터페이스를 제공하거나 사용하는 양쪽 컴포넌트가 상대방이 어떤 언어로 작성됐는지 신경쓸 필요가 없다.</p>

<p>인터페이스를 XPIDL 컴파일러에 적용하면, XPT 또는 타입 라이브러리 파일을 생성한다. XPConnect는 XPT 파일로부터 얻은 정보를 사용해서 C++ 객체와 JavaScript 객체 간의 통신을 XPCOM 인터페이스를 통해서 투명하게 구현한다. 그러므로 C++로만 개발하더라도 XPCOM 인터페이스를 생성해서 코드에 포함시키는 것이 매우 중요하다. 브라우저의 특정 부분만 JS로 구현된 것이 아니라, 향후에도 누군가 JS 기반 코드를 사용해서 당신이 작성한 컴포넌트와 상호작용하도록 할 수도 있다.</p>

<p>현재 모질라에서 XPConnect는 C++와 JS 간의 상호작용을 가능하게 한다. 다른 언어(Python 등)에서 접근할 수 있도록 하는 모듈은 별도로 개발 중이다.</p>

<h4 id="String_.ED.81.B4.EB.9E.98.EC.8A.A4" name="String_.ED.81.B4.EB.9E.98.EC.8A.A4">String 클래스</h4>

<p>웹 브라우징은 일반적으로 많은 양의 문자열 처리를 필요로 한다. 모질라는 문자열을 처리하고 효율적으로 빠르게 출력하기 위한 C++ 클래스 라이브러리를 개발해왔다. 모질라는 객체 간 통신을 간단하게 하고 에러를 줄이기 위해 인터페이스, 즉 추상 클래스를 사용한다. 같은 이유로 String 클래스 계층도 <code>nsAString</code>, <code>nsASingleFragmentString</code>, <code>nsAFlatString</code> 등의 몇가지 추상 클래스를 앞세운다. (이 클래스들은 2바이트 문자열을 참조한다. <code>nsACString</code>로 시작하는 1바이트 문자열을 참조하는 계층이 동일한 구조로 별도로 존재한다.) <code>nsAString</code>은 문자로 구성된 문자열이라는 것만 보장한다. <code>nsASingleFragmentString</code>는 문자들이 한 버퍼에 저장되어 있음을 보장한다. <code>nsAFlatString</code>는 문자들이 하나의 null로 끝나는 버퍼에 들어있음을 보장한다. 하부에는 구상 클래스가 있지만, 되도록이면 가능한한 가장 추상적인 타입을 사용하는 것이 좋다. 예를 들어 문자열 접합(concatenation)은 포인터를 사용해서 가상으로 이루어질 수 있으며, 그 결과는 다른 문자열처럼 사용될 수 있는 nsAString이다. 덕분에 메모리 할당과 복사를 하지 않아도 된다. 더 자세한 정보는 "<a href="ko/XPCOM/Strings">Guide to the Mozilla string classes</a>"를 참고하라.</p>

<h4 id="XUL.2FXBL" name="XUL.2FXBL">XUL/XBL</h4>

<p>이 마지막 모질라 기술은 애플리케이션의 UI를 어떻게 만들 것이냐에 따라 선택해서 사용할 수 있다. <a href="ko/XUL">XUL</a>은 모질라의 매우 유연한 XML UI 언어이다. 매우 다양한 플랫폼 독립적인 위젯을 제공하며 위젯들을 사용해서 UI를 작성할 수 있다. 넷스케이프와 모질라는 모두 XUL을 인터페이스로 사용하지만, 모든 임베딩 애플리케이션 개발자들이 XUL을 사용하는 것은 아니다. XBL(eXtensible Binding Language)은 XUL의 XML 요소에 동작을 추가하는 데 사용할 수 있다. XUL에 대한 더 자세한 정보는 <a class="external" href="http://www.mozilla.org/xpfe/xulref/">XUL Programmer's Reference</a>에서, <a href="ko/XBL">XBL</a><a href="ko/XBL/XBL_1.0_Reference">XBL:XBL_1.0_Reference</a>에서 찾을 수 있다. <a class="external" href="http://www.xulplanet.com/">XULPlanet</a>에도 XUL에 관련된 좋은 정보가 많다.</p>

<h3 id=".EC.B6.94.EA.B0.80.EC.A0.81.EC.9D.B8_.EA.B8.B0.EB.8A.A5.EB.93.A4.EC.9D.98_.EC.84.A0.ED.83.9D" name=".EC.B6.94.EA.B0.80.EC.A0.81.EC.9D.B8_.EA.B8.B0.EB.8A.A5.EB.93.A4.EC.9D.98_.EC.84.A0.ED.83.9D">추가적인 기능들의 선택</h3>

<p>이 문서(8/19/02)에 따르면, Gecko는 부분적으로 모듈화 되어있는 렌더링 엔진이다. 기본적인 브라우징외의 어떤 기능들은 항상 Gecko와 함께 임베디드 되어있고, 구조적인 결정의 결과들로 인해 항상 그래야 한다. (현재 어느부분은 Gecko와 함께 임베디드 되어있지만, 미래에 어떤 부분들은 분리되어 질 수 있다.) 그리고, 어떤 부분은 옵션으로 사용 가능하다. 아래의 테이블에 이 추가적인 기능들의 대한 현재 상태가 기술되어 있다.</p>

<table>
 <tbody>
  <tr>
   <th>Functions</th>
   <th>Status Now</th>
   <th>Status in Future</th>
  </tr>
  <tr>
   <td>FTP support</td>
   <td>Optional</td>
   <td></td>
  </tr>
  <tr>
   <td>HTTPS support</td>
   <td>Optional</td>
   <td></td>
  </tr>
  <tr>
   <td>International character support</td>
   <td>Optional</td>
   <td></td>
  </tr>
  <tr>
   <td>XUL support</td>
   <td>Required</td>
   <td>Probably optional</td>
  </tr>
  <tr>
   <td>Network support</td>
   <td>Required</td>
   <td>Maybe optional</td>
  </tr>
  <tr>
   <td>JavaScript support</td>
   <td>Required</td>
   <td>Maybe optional</td>
  </tr>
  <tr>
   <td>CSS support</td>
   <td>Required</td>
   <td>Always required</td>
  </tr>
  <tr>
   <td>DOM support</td>
   <td>Required</td>
   <td>Probably always</td>
  </tr>
  <tr>
   <td>XML support</td>
   <td>Required</td>
   <td>Probably always</td>
  </tr>
 </tbody>
</table>

<p>이번에 렌더링 엔진 Gecko와 함께 임베디드된 Mozilla의 에디터는 발전을 계속하고 있다는 하나의 불확실한 제의이다. 임베디드 될수 있는 에디터의 상태에 관해 더 정보를 보고 싶다면, <a class="external" href="http://www.mozilla.org/editor/Editor_Embedding_Guide.html" rel="freelink">http://www.mozilla.org/editor/Editor...ing_Guide.html</a> 을 참조하라.</p>

<h2 id="What_Gecko_Provides" name="What_Gecko_Provides">What Gecko Provides</h2>

<p>The following is a description of some of the interfaces most commonly used in embedding Gecko. It is by no means an exhaustive list of the available interfaces. The interfaces in this section are on classes provided by Mozilla. There is also a set of interfaces for which Gecko expects the embedder to provide the implementation. A sample of those are covered in the next section.</p>

<h3 id=".EC.B4.88.EA.B8.B0.ED.99.94.EC.99.80_Teardown" name=".EC.B4.88.EA.B8.B0.ED.99.94.EC.99.80_Teardown">초기화와 Teardown</h3>

<p>Gecko를 초기화하고 종료하는데 사용되는 2개의 C++ 함수가 있다. 초기화 함수(<a class="external" href="http://mozilla.org/projects/embedding/embedapiref/embedapi2.html#1099700">NS_InitEmbedding</a>)는 Gecko를 사용하기 전에 반드시 호출하여야 한다. 이것은 XPCOM을 안전하게 시작할 수 있도록, 필요하다면 컴포넌트 레지스트리를 생성하며, Global service를 기동한다. Shutdown 함수(<a class="external" href="http://mozilla.org/projects/embedding/embedapiref/embedapi2.html#1101115">NS_TermEmbedding</a>)는 Gecko embedding layer를 종료하며, Global service를 안전하게 unload 하며, File을 닫고, XPCOM을 종료한다.</p>

<h3 id="nsIWebBrowser" name="nsIWebBrowser"><a class="external" href="http://mozilla.org/projects/embedding/embedapiref/embedapi4.html">nsIWebBrowser</a></h3>

<p>Use of this interface during initialization allows embedders to associate a new <code>nsWebBrowser</code> instance (an object representing the "client-area" of a typical browser window) with the embedder's chrome and to register any listeners. The interface may also be used at runtime to obtain the content DOM window and from that the rest of the DOM.</p>

<p>The <a class="external" href="http://xulplanet.com/references/xpcomref/ifaces/nsIWebBrowser.html">XULPlanet <code>nsWebBrowser</code> reference</a> also has a lot of useful information on this class.</p>

<h3 id="nsIWebBrowserSetup" name="nsIWebBrowserSetup"><a class="external" href="http://www.mozilla.org/projects/embedding/embedapiref/embedapi10.html">nsIWebBrowserSetup</a></h3>

<p>이 인터페이스는 브라우져 윈도우가 열리기 전에, 기본 프로퍼티(이미지를 로드 할 것인지 안할 것인지 같은)를 설정한다.</p>

<h3 id="nsIWebNavigation" name="nsIWebNavigation"><a class="external" href="http://www.xulplanet.com/references/xpcomref/ifaces/nsIWebNavigation.html">nsIWebNavigation</a></h3>

<p><code>nsIWebNavigation</code> 인터페이스는 웹 브라우져 Instance로 URI를 로드하며, Sessoin History 기능(Back이나 Forward 같은)에 접근할 수 있도록 한다. 2006년 6월 6일, 이 인터페이스는 아직 Frozen되지 않았다.</p>

<h3 id="nsIWebBrowserPersist" name="nsIWebBrowserPersist"><a class="external" href="http://www.xulplanet.com/references/xpcomref/ifaces/nsIWebBrowserPersist.html">nsIWebBrowserPersist</a></h3>

<p><code>nsIWebBrowserPersist</code> 인터페이스는 File로 URI를 저장할 수 있도록 한다. 2006년 6월 6일, 이 인터페이스는 아직 Frozen되지 않았다.</p>

<h3 id="nsIBaseWindow" name="nsIBaseWindow"><a class="external" href="http://www.xulplanet.com/references/xpcomref/ifaces/nsIBaseWindow.html">nsIBaseWindow</a></h3>

<p><code>nsIBaseWindow</code> 인터페이스는 일반적인 Windows나 기본 기능(size, position, windows title 반환 등)이 동작 할 수 있도록 한다. 2006년 6월 6일 이 인터페이스는 아직 Frozen되지 않았다.</p>

<h3 id="nsISHistory" name="nsISHistory"><a class="external" href="http://mozilla.org/projects/embedding/embedapiref/embedapi58.html">nsISHistory</a></h3>

<p><code>nsISHistory</code> 인터페이스는 Session histroy 정보에 접근하며, 삭제 할 수 있도록 한다.</p>

<h3 id="nsIWebBrowserFind" name="nsIWebBrowserFind"><a class="external" href="http://mozilla.org/projects/embedding/embedapiref/embedapi14.html">nsIWebBrowserFind</a></h3>

<p><code>nsIWebBrowserFind</code> 인터페이스는 브라우져 Window에서 문자열 검색을 설정, 실행 할 수 있도록 제어한다.</p>

<h2 id="What_You_Provide" name="What_You_Provide">What You Provide</h2>

<p>The following is a description of some of the more common embedder-provided interfaces used in embedding Gecko. It is by no means an exhaustive list of the available interfaces.</p>

<h3 id="nsIWebBrowserChrome" name="nsIWebBrowserChrome"><a class="external" href="http://mozilla.org/projects/embedding/embedapiref/embedapi6.html">nsIWebBrowserChrome</a></h3>

<p>The <code>nsIWebBrowserChrome</code> interface corresponds to the top-level, outermost window containing an embedded Gecko web browser. You associate it with the WebBrowser through the <code>nsIWebBrowser</code> interface. It provides control over window setup and whether or not the window is modal. It must be implemented.</p>

<h3 id="nsIEmbeddingSiteWindow" name="nsIEmbeddingSiteWindow"><a class="external" href="http://www.mozilla.org/projects/embedding/embedapiref/embedapi12.html">nsIEmbeddingSiteWindow</a></h3>

<p>The <code>nsIEmbeddingSiteWindow</code> interface provides Gecko with the means to call up to the host to resize the window, hide or show it and set/get its title. It must be implemented.</p>

<h3 id="nsIWebProgressListener" name="nsIWebProgressListener"><a href="ko/NsIWebProgressListener">nsIWebProgressListener</a></h3>

<p>The <code>nsIWebProgressListener</code> interface provides information on the progress of loading documents. It is added to the WebBrowser through the <code>nsIWebBrowser</code> interface. It must be implemented. As of this writing (8/19/02), it is not frozen.</p>

<h3 id="nsISHistoryListener" name="nsISHistoryListener"><a class="external" href="http://mozilla.org/projects/embedding/embedapiref/embedapi59.html">nsISHistoryListener</a></h3>

<p>The <code>nsISHistoryListener</code> interface is implemented by embedders who wish to receive notifications about activities in session history. A history listener is notified when pages are added, removed and loaded from session history. It is associated with Gecko through the <code>nsIWebBrowser</code> interface. Implementation is optional.</p>

<h3 id="nsIContextMenuListener" name="nsIContextMenuListener"><a class="external" href="http://mozilla.org/projects/embedding/embedapiref/embedapi5.html">nsIContextMenuListener</a></h3>

<p>The <code>nsIContextMenuListener</code> interface is implemented by embedders who wish to receive notifications for context menu events, i.e. generated by a user right-mouse clicking on a link. It should be implemented on the web browser chrome object associated with the window for which notifications are required. When a context menu event occurs, the browser will call this interface if present. Implementation is optional.</p>

<h3 id="nsIPromptService" name="nsIPromptService"><a href="ko/NsIPromptService">nsIPromptService</a></h3>

<p>The <code>nsIPromptServices</code> interface allows the embedder to override Mozilla's standard prompts: alerts, dialog boxes, and check boxes and so forth. The class that implements these embedder specific prompts must be registered with the Component Manager using the same CID and contract ID that the Mozilla standard prompt service normally uses. Implementation is optional. As of this writing (8/19/02), this interface is not frozen.</p>

<h2 id="Common_Embedding_Tasks" name="Common_Embedding_Tasks">Common Embedding Tasks</h2>

<p>The following is a series of code snippets (taken from MFCEmbed, the Windows based embedding Gecko sample) which demonstrate very briefly implementation associated with common embedding tasks.To see all the files associated with this sample, go to <a class="external" href="http://lxr.mozilla.org/seamonkey/source/embedding/tests/mfcembed/" rel="freelink">http://lxr.mozilla.org/seamonkey/sou...ests/mfcembed/</a>. There are also Linux- and Mac OS-based examples.</p>

<h3 id="Gecko_setup" name="Gecko_setup">Gecko setup</h3>

<p>The Gecko embedding layer must be initialized before you can use Gecko. This ensures XPCOM is started, creates the component registry if necessary, and starts global services. There is an equivalent shutdown procedure.</p>

<p>Note that the embedding layer is started up by passing it two parameters. The first indicates where the executable is stored on the file system (<code>nsnull</code> indicates the working directory). The second indicates the file location object "provider" that specifies to Gecko where to find profiles, the component registry preferences, and so on.</p>

<pre>nsresult rv;
rv = NS_InitEmbedding(nsnull, provider);
if(NS_FAILED(rv))
{
ASSERT(FALSE);
return FALSE;
}
</pre>

<h3 id="Creating_a_browser_instance" name="Creating_a_browser_instance">Creating a browser instance</h3>

<p>The embedder-provided BrowserView object calls its method <code>CreateBrowser()</code>. Each browser object (a webbrowser) represents a single browser window. Notice the utility directive <code>do_CreateInstance()</code> and the use of macros.</p>

<pre>//Create an instance of the Mozilla embeddable browser

HRESULT CBrowserView::CreateBrowser()
{
// Create a web shell
nsresult rv;
mWebBrowser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID, &amp;rv);
if(NS_FAILED(rv))
return rv;
</pre>

<p>Once the <code>nsWebBrowser</code> object is created the application uses <code>do_QueryInterface()</code> to load a pointer to the <a class="external" href="http://www.xulplanet.com/references/xpcomref/ifaces/nsIWebNavigation.html">nsIWebNavigation</a> interface into the <code>mWebNav</code> member variable. This will be used later for web page navigation.</p>

<pre>rv = NS_OK;
mWebNav = do_QueryInterface(mWebBrowser, &amp;rv);
if(NS_FAILED(rv))
return rv;
</pre>

<p>Next the embedder-provided <code>CBrowserImpl</code> object is created. Gecko requires that some interfaces be implemented by the embedder so that Gecko can communicate with the embedding application. See the <a href="#What_You_Provide">What You Provide Section</a>. In the sample, <code>CBrowserImpl</code> is the object that implements those required interfaces. It will be passed into the <code>SetContainerWindow()</code> call below.</p>

<pre>mpBrowserImpl = new CBrowserImpl();
if(mpBrowserImpl == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
</pre>

<p>The <code>mWebBrowser</code> interface pointer is then passed to the <code>CBrowserImpl</code> object via its <code>Init()</code> method. A second pointer to the platform specific <code>BrowserFrameGlue</code> interface is also passed in and saved. The <code>BrowserFrameGlue</code> pointer allows <code>CBrowserImpl</code> to call methods to update status bars, progress bars, and so forth.</p>

<pre>mpBrowserImpl-&gt;Init(mpBrowserFrameGlue, mWebBrowser);
mpBrowserImpl-&gt;AddRef();
</pre>

<p>Next the embedder-supplied chrome object is associated with the webbrowser. Note the use of an <code>nsCOMPtr</code>.</p>

<pre>mWebBrowser-&gt;SetContainerWindow
	(NS_STATIC_CAST(nsIWebBrowserChrome*, mpBrowserImpl));
nsCOMPtr&lt;nsIWebBrowserSetup&gt;setup(do_QueryInterface(mWebBrowser));
if (setup)
	setup-&gt;SetProperty(nsIWebBrowserSetup::SETUP_IS_CHROME_WRAPPER,PR_TRUE);
</pre>

<p>Then, the real webbrowser window is created.</p>

<pre>rv = NS_OK;
mBaseWindow = do_QueryInterface(mWebBrowser, &amp;rv);
if(NS_FAILED(rv))
return rv;
</pre>

<h3 id="Binding_a_window" name="Binding_a_window">Binding a window</h3>

<p>Basic location information is passed in.</p>

<pre>RECT rcLocation;
GetClientRect(&amp;rcLocation);
if(IsRectEmpty(&amp;rcLocation))
{
	rcLocation.bottom++;
	rcLocation.top++;
}
rv = mBaseWindow-&gt;InitWindow(nsNativeWidget(m_hWnd),
		nsnull,0, 0, rcLocation.right - rcLocation.left,
		rcLocation.bottom - rcLocation.top);
rv = mBaseWindow-&gt;Create();
</pre>

<p>Note the <code>m_hWnd</code> passed into the call above to <code>InitWindow()</code>. (<code>CBrowserView</code> inherits the <code>m_hWnd</code> from <code>CWnd</code>). This <code>m_hWnd</code> will be used as the parent window by the embeddable browser.</p>

<h3 id="Adding_a_listener" name="Adding_a_listener">Adding a listener</h3>

<p>The <code>BrowserImpl</code> object is added as an <a href="ko/NsIWebProgressListener">nsIWebProgressListener</a>. It will now receive progress messages. These callbacks will be used to update the status/progress bars.</p>

<pre>nsWeakPtr weakling
	(dont_AddRef(NS_GetWeakReference(NS_STATIC_CAST(nsIWebProgressListener*,
			mpBrowserImpl))));
void mWebBrowser-&gt;AddWebBrowserListener(weakling, NS_GET_IID(nsIWebProgressListener));
</pre>

<p>Finally the webbrowser window is shown.</p>

<pre>mBaseWindow-&gt;SetVisibility(PR_TRUE);
</pre>

<h3 id="Using_session_history_to_navigate" name="Using_session_history_to_navigate">Using session history to navigate</h3>

<p>The pointer to <a class="external" href="http://www.xulplanet.com/references/xpcomref/ifaces/nsIWebNavigation.html">nsIWebNavigation</a> saved above is used to move back through session history.</p>

<pre>void CBrowserView::OnNavBack()
{
if(mWebNav)
	mWebNav-&gt;GoBack();
}
</pre>

<h2 id="Appendix_Data_Flow_Inside_Gecko" name="Appendix:_Data_Flow_Inside_Gecko">Appendix: Data Flow Inside Gecko</h2>

<p>While it isn't strictly necessary for embedders to understand how Gecko does what it does, a brief overview of the main structures involved as Gecko puts bits on a display may be helpful.</p>



<p>HTML data comes into Gecko either from the network or a local source. The first thing that happens is that it is parsed, using Gecko's own HTML parser. Then the Content Model arranges this parsed data into a large tree. The tree is also known as the "Document" and its structure is based on the W3C Document Object Model. Any use of DOM APIs manipulates the data in the Content Model.</p>

<p>Next the data is put into frames using CSS and the Frame Constructor. A frame in this sense (which is not the same thing as an HTML frame) is basically an abstract box within which a DOM element will be displayed. This process produces a Frame Tree, which, like the Content Model, is a tree of data, but this time focused not on the logical relationship among the elements but on the underlying calculations needed to display the data. In the beginning a frame has no size. Using CSS rules specifying how the elements of the DOM should look when they are displayed, including information like font type or image size, the eventual size of each frame is calculated. Because the same data may need to be displayed in different ways -- to a monitor and to a printer, for example -- a particular Content Model may have more than one Frame Tree associated with it. In such a case, each individual Frame Tree would belong to a different "presentation" mode.</p>

<p>Calculations continue as new information flows into the system using a process called <strong>reflow</strong>. As information in the Frame Tree changes, the section of the Frame Tree involved is marked "dirty" by the Frame Constructor. Reflow repeatedly steps through the tree, processing every "dirty" item it encounters until all the items it encounters are "clean". Every item in the Frame Tree has a pointer back to its corresponding item in the Content Model. A change in the Content Model, say through using the DOM APIs to change an element from hidden to visible, produces an equivalent change in the Frame Tree. It's important to note that all of these operations are purely data manipulations. Painting to the display itself is not yet involved at this point.</p>

<p>The next stage is the View Manager. With a few small exceptions that have to do with prompting the Frame Constructor to load graphics, the View Manager is the first place in the process that accesses the native OS. Delaying OS access until this point both helps Gecko to run more quickly and makes cross-platform issues easier to deal with. The View Manger is the place where Gecko figures out where on the display the data will need to be drawn. It then tells the system that that area is "invalid" and needs to be repainted. The actual painting is managed by the gfx submodule, while other low-level system operations are run through the widget submodule, which handles things like platform specific event (mouse clicks and so forth) processing loops and accessing system defaults (colors, fonts, etc.) Both gfx and widget are system specific.</p>

<p>If you want to take a look at the code underlying these structures, the code for the Content Model can be found in &lt;tt&gt;/mozilla/content&lt;/tt&gt;, for the Frame Constructor, CSS, and Reflow in &lt;tt&gt;/mozilla/layout&lt;/tt&gt;, for the View Manager in &lt;tt&gt;/mozilla/view&lt;/tt&gt;, and for the DOM APIs in &lt;tt&gt;/mozilla/dom&lt;/tt&gt;.</p>

<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:jeev@netscape.com">Ellen Evans</a></li>
 <li>Last Updated Date: August 19, 2002</li>
 <li>Copyright Information: Copyright (C) <a class="link-mailto" href="mailto:jeev@netscape.com">Ellen Evans</a></li>
</ul>
</div>