|
1 /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 * vim: set ts=2 sw=2 et tw=79: |
|
3 * |
|
4 * This Source Code Form is subject to the terms of the Mozilla Public |
|
5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
7 |
|
8 // Local Includes |
|
9 #include "nsContentTreeOwner.h" |
|
10 #include "nsXULWindow.h" |
|
11 |
|
12 // Helper Classes |
|
13 #include "nsIServiceManager.h" |
|
14 #include "nsAutoPtr.h" |
|
15 |
|
16 // Interfaces needed to be included |
|
17 #include "nsIDOMNode.h" |
|
18 #include "nsIDOMElement.h" |
|
19 #include "nsIDOMNodeList.h" |
|
20 #include "nsIDOMWindow.h" |
|
21 #include "nsIDOMChromeWindow.h" |
|
22 #include "nsIBrowserDOMWindow.h" |
|
23 #include "nsIDOMXULElement.h" |
|
24 #include "nsIEmbeddingSiteWindow.h" |
|
25 #include "nsIPrompt.h" |
|
26 #include "nsIAuthPrompt.h" |
|
27 #include "nsIWindowMediator.h" |
|
28 #include "nsIXULBrowserWindow.h" |
|
29 #include "nsIPrincipal.h" |
|
30 #include "nsIURIFixup.h" |
|
31 #include "nsCDefaultURIFixup.h" |
|
32 #include "nsIWebNavigation.h" |
|
33 #include "nsDocShellCID.h" |
|
34 #include "nsIExternalURLHandlerService.h" |
|
35 #include "nsIMIMEInfo.h" |
|
36 #include "nsIWidget.h" |
|
37 #include "mozilla/BrowserElementParent.h" |
|
38 |
|
39 #include "nsIDOMDocument.h" |
|
40 #include "nsIScriptObjectPrincipal.h" |
|
41 #include "nsIURI.h" |
|
42 #include "nsIDocument.h" |
|
43 #if defined(XP_MACOSX) |
|
44 #include "nsThreadUtils.h" |
|
45 #endif |
|
46 |
|
47 #include "mozilla/Preferences.h" |
|
48 #include "mozilla/dom/Element.h" |
|
49 #include "mozilla/dom/ScriptSettings.h" |
|
50 |
|
51 using namespace mozilla; |
|
52 |
|
53 //***************************************************************************** |
|
54 //*** nsSiteWindow declaration |
|
55 //***************************************************************************** |
|
56 |
|
57 class nsSiteWindow : public nsIEmbeddingSiteWindow |
|
58 { |
|
59 public: |
|
60 nsSiteWindow(nsContentTreeOwner *aAggregator); |
|
61 virtual ~nsSiteWindow(); |
|
62 |
|
63 NS_DECL_ISUPPORTS |
|
64 NS_DECL_NSIEMBEDDINGSITEWINDOW |
|
65 |
|
66 private: |
|
67 nsContentTreeOwner *mAggregator; |
|
68 }; |
|
69 |
|
70 //***************************************************************************** |
|
71 //*** nsContentTreeOwner: Object Management |
|
72 //***************************************************************************** |
|
73 |
|
74 nsContentTreeOwner::nsContentTreeOwner(bool fPrimary) : mXULWindow(nullptr), |
|
75 mPrimary(fPrimary), mContentTitleSetting(false) |
|
76 { |
|
77 // note if this fails, QI on nsIEmbeddingSiteWindow(2) will simply fail |
|
78 mSiteWindow = new nsSiteWindow(this); |
|
79 } |
|
80 |
|
81 nsContentTreeOwner::~nsContentTreeOwner() |
|
82 { |
|
83 delete mSiteWindow; |
|
84 } |
|
85 |
|
86 //***************************************************************************** |
|
87 // nsContentTreeOwner::nsISupports |
|
88 //***************************************************************************** |
|
89 |
|
90 NS_IMPL_ADDREF(nsContentTreeOwner) |
|
91 NS_IMPL_RELEASE(nsContentTreeOwner) |
|
92 |
|
93 NS_INTERFACE_MAP_BEGIN(nsContentTreeOwner) |
|
94 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocShellTreeOwner) |
|
95 NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeOwner) |
|
96 NS_INTERFACE_MAP_ENTRY(nsIBaseWindow) |
|
97 NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome) |
|
98 NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome2) |
|
99 NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome3) |
|
100 NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor) |
|
101 NS_INTERFACE_MAP_ENTRY(nsIWindowProvider) |
|
102 // NOTE: This is using aggregation because there are some properties and |
|
103 // method on nsIBaseWindow (which we implement) and on |
|
104 // nsIEmbeddingSiteWindow (which we also implement) that have the same name. |
|
105 // And it just so happens that we want different behavior for these methods |
|
106 // and properties depending on the interface through which they're called |
|
107 // (SetFocus() is a good example here). If it were not for that, we could |
|
108 // ditch the aggregation and just deal with not being able to use NS_DECL_* |
|
109 // macros for this stuff.... |
|
110 NS_INTERFACE_MAP_ENTRY_AGGREGATED(nsIEmbeddingSiteWindow, mSiteWindow) |
|
111 NS_INTERFACE_MAP_END |
|
112 |
|
113 //***************************************************************************** |
|
114 // nsContentTreeOwner::nsIInterfaceRequestor |
|
115 //***************************************************************************** |
|
116 |
|
117 NS_IMETHODIMP nsContentTreeOwner::GetInterface(const nsIID& aIID, void** aSink) |
|
118 { |
|
119 NS_ENSURE_ARG_POINTER(aSink); |
|
120 *aSink = 0; |
|
121 |
|
122 if(aIID.Equals(NS_GET_IID(nsIPrompt))) { |
|
123 NS_ENSURE_STATE(mXULWindow); |
|
124 return mXULWindow->GetInterface(aIID, aSink); |
|
125 } |
|
126 if(aIID.Equals(NS_GET_IID(nsIAuthPrompt))) { |
|
127 NS_ENSURE_STATE(mXULWindow); |
|
128 return mXULWindow->GetInterface(aIID, aSink); |
|
129 } |
|
130 if (aIID.Equals(NS_GET_IID(nsIDocShellTreeItem))) { |
|
131 NS_ENSURE_STATE(mXULWindow); |
|
132 nsCOMPtr<nsIDocShell> shell; |
|
133 mXULWindow->GetDocShell(getter_AddRefs(shell)); |
|
134 if (shell) |
|
135 return shell->QueryInterface(aIID, aSink); |
|
136 return NS_ERROR_FAILURE; |
|
137 } |
|
138 |
|
139 if (aIID.Equals(NS_GET_IID(nsIDOMWindow))) { |
|
140 NS_ENSURE_STATE(mXULWindow); |
|
141 nsCOMPtr<nsIDocShellTreeItem> shell; |
|
142 mXULWindow->GetPrimaryContentShell(getter_AddRefs(shell)); |
|
143 if (shell) { |
|
144 nsCOMPtr<nsIInterfaceRequestor> thing(do_QueryInterface(shell)); |
|
145 if (thing) |
|
146 return thing->GetInterface(aIID, aSink); |
|
147 } |
|
148 return NS_ERROR_FAILURE; |
|
149 } |
|
150 |
|
151 if (aIID.Equals(NS_GET_IID(nsIXULWindow))) { |
|
152 NS_ENSURE_STATE(mXULWindow); |
|
153 return mXULWindow->QueryInterface(aIID, aSink); |
|
154 } |
|
155 |
|
156 return QueryInterface(aIID, aSink); |
|
157 } |
|
158 |
|
159 //***************************************************************************** |
|
160 // nsContentTreeOwner::nsIDocShellTreeOwner |
|
161 //***************************************************************************** |
|
162 |
|
163 NS_IMETHODIMP nsContentTreeOwner::FindItemWithName(const char16_t* aName, |
|
164 nsIDocShellTreeItem* aRequestor, nsIDocShellTreeItem* aOriginalRequestor, |
|
165 nsIDocShellTreeItem** aFoundItem) |
|
166 { |
|
167 NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID); |
|
168 |
|
169 NS_ENSURE_ARG_POINTER(aFoundItem); |
|
170 |
|
171 *aFoundItem = nullptr; |
|
172 |
|
173 bool fIs_Content = false; |
|
174 |
|
175 /* Special Cases */ |
|
176 if (!aName || !*aName) |
|
177 return NS_OK; |
|
178 |
|
179 nsDependentString name(aName); |
|
180 |
|
181 if (name.LowerCaseEqualsLiteral("_blank")) |
|
182 return NS_OK; |
|
183 // _main is an IE target which should be case-insensitive but isn't |
|
184 // see bug 217886 for details |
|
185 if (name.LowerCaseEqualsLiteral("_content") || |
|
186 name.EqualsLiteral("_main")) { |
|
187 // If we're being called with an aRequestor and it's targetable, just |
|
188 // return it -- _main and _content from inside targetable content shells |
|
189 // should just be that content shell. Note that we don't have to worry |
|
190 // about the case when it's not targetable because it's primary -- that |
|
191 // will Just Work when we call GetPrimaryContentShell. |
|
192 NS_ENSURE_STATE(mXULWindow); |
|
193 if (aRequestor) { |
|
194 // This better be the root item! |
|
195 #ifdef DEBUG |
|
196 nsCOMPtr<nsIDocShellTreeItem> debugRoot; |
|
197 aRequestor->GetSameTypeRootTreeItem(getter_AddRefs(debugRoot)); |
|
198 NS_ASSERTION(SameCOMIdentity(debugRoot, aRequestor), |
|
199 "Bogus aRequestor"); |
|
200 #endif |
|
201 |
|
202 int32_t count = mXULWindow->mTargetableShells.Count(); |
|
203 for (int32_t i = 0; i < count; ++i) { |
|
204 nsCOMPtr<nsIDocShellTreeItem> item = |
|
205 do_QueryReferent(mXULWindow->mTargetableShells[i]); |
|
206 if (SameCOMIdentity(item, aRequestor)) { |
|
207 NS_ADDREF(*aFoundItem = aRequestor); |
|
208 return NS_OK; |
|
209 } |
|
210 } |
|
211 } |
|
212 mXULWindow->GetPrimaryContentShell(aFoundItem); |
|
213 if(*aFoundItem) |
|
214 return NS_OK; |
|
215 // Fall through and keep looking... |
|
216 fIs_Content = true; |
|
217 } |
|
218 |
|
219 nsCOMPtr<nsIWindowMediator> windowMediator(do_GetService(kWindowMediatorCID)); |
|
220 NS_ENSURE_TRUE(windowMediator, NS_ERROR_FAILURE); |
|
221 |
|
222 nsCOMPtr<nsISimpleEnumerator> windowEnumerator; |
|
223 NS_ENSURE_SUCCESS(windowMediator->GetXULWindowEnumerator(nullptr, |
|
224 getter_AddRefs(windowEnumerator)), NS_ERROR_FAILURE); |
|
225 |
|
226 bool more; |
|
227 |
|
228 windowEnumerator->HasMoreElements(&more); |
|
229 while(more) { |
|
230 nsCOMPtr<nsISupports> nextWindow = nullptr; |
|
231 windowEnumerator->GetNext(getter_AddRefs(nextWindow)); |
|
232 nsCOMPtr<nsIXULWindow> xulWindow(do_QueryInterface(nextWindow)); |
|
233 NS_ENSURE_TRUE(xulWindow, NS_ERROR_FAILURE); |
|
234 |
|
235 if (fIs_Content) { |
|
236 xulWindow->GetPrimaryContentShell(aFoundItem); |
|
237 } else { |
|
238 // Get all the targetable windows from xulWindow and search them |
|
239 nsRefPtr<nsXULWindow> win; |
|
240 xulWindow->QueryInterface(NS_GET_IID(nsXULWindow), getter_AddRefs(win)); |
|
241 if (win) { |
|
242 int32_t count = win->mTargetableShells.Count(); |
|
243 int32_t i; |
|
244 for (i = 0; i < count && !*aFoundItem; ++i) { |
|
245 nsCOMPtr<nsIDocShellTreeItem> shellAsTreeItem = |
|
246 do_QueryReferent(win->mTargetableShells[i]); |
|
247 if (shellAsTreeItem) { |
|
248 // Get the root tree item of same type, since roots are the only |
|
249 // things that call into the treeowner to look for named items. |
|
250 // XXXbz ideally we could guarantee that mTargetableShells only |
|
251 // contains roots, but the current treeowner apis don't allow |
|
252 // that... yet. |
|
253 nsCOMPtr<nsIDocShellTreeItem> root; |
|
254 shellAsTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(root)); |
|
255 NS_ASSERTION(root, "Must have root tree item of same type"); |
|
256 shellAsTreeItem.swap(root); |
|
257 if (aRequestor != shellAsTreeItem) { |
|
258 // Do this so we can pass in the tree owner as the |
|
259 // requestor so the child knows not to call back up. |
|
260 nsCOMPtr<nsIDocShellTreeOwner> shellOwner; |
|
261 shellAsTreeItem->GetTreeOwner(getter_AddRefs(shellOwner)); |
|
262 nsCOMPtr<nsISupports> shellOwnerSupports = |
|
263 do_QueryInterface(shellOwner); |
|
264 |
|
265 shellAsTreeItem->FindItemWithName(aName, shellOwnerSupports, |
|
266 aOriginalRequestor, |
|
267 aFoundItem); |
|
268 } |
|
269 } |
|
270 } |
|
271 } |
|
272 } |
|
273 |
|
274 if (*aFoundItem) |
|
275 return NS_OK; |
|
276 |
|
277 windowEnumerator->HasMoreElements(&more); |
|
278 } |
|
279 return NS_OK; |
|
280 } |
|
281 |
|
282 NS_IMETHODIMP |
|
283 nsContentTreeOwner::ContentShellAdded(nsIDocShellTreeItem* aContentShell, |
|
284 bool aPrimary, bool aTargetable, |
|
285 const nsAString& aID) |
|
286 { |
|
287 NS_ENSURE_STATE(mXULWindow); |
|
288 return mXULWindow->ContentShellAdded(aContentShell, aPrimary, aTargetable, |
|
289 aID); |
|
290 } |
|
291 |
|
292 NS_IMETHODIMP |
|
293 nsContentTreeOwner::ContentShellRemoved(nsIDocShellTreeItem* aContentShell) |
|
294 { |
|
295 NS_ENSURE_STATE(mXULWindow); |
|
296 return mXULWindow->ContentShellRemoved(aContentShell); |
|
297 } |
|
298 |
|
299 NS_IMETHODIMP |
|
300 nsContentTreeOwner::GetPrimaryContentShell(nsIDocShellTreeItem** aShell) |
|
301 { |
|
302 NS_ENSURE_STATE(mXULWindow); |
|
303 return mXULWindow->GetPrimaryContentShell(aShell); |
|
304 } |
|
305 |
|
306 NS_IMETHODIMP |
|
307 nsContentTreeOwner::GetContentWindow(JSContext* aCx, |
|
308 JS::MutableHandle<JS::Value> aVal) |
|
309 { |
|
310 NS_ENSURE_STATE(mXULWindow); |
|
311 return NS_ERROR_NOT_IMPLEMENTED; |
|
312 } |
|
313 |
|
314 NS_IMETHODIMP nsContentTreeOwner::SizeShellTo(nsIDocShellTreeItem* aShellItem, |
|
315 int32_t aCX, int32_t aCY) |
|
316 { |
|
317 NS_ENSURE_STATE(mXULWindow); |
|
318 return mXULWindow->SizeShellTo(aShellItem, aCX, aCY); |
|
319 } |
|
320 |
|
321 NS_IMETHODIMP |
|
322 nsContentTreeOwner::SetPersistence(bool aPersistPosition, |
|
323 bool aPersistSize, |
|
324 bool aPersistSizeMode) |
|
325 { |
|
326 NS_ENSURE_STATE(mXULWindow); |
|
327 nsCOMPtr<dom::Element> docShellElement = mXULWindow->GetWindowDOMElement(); |
|
328 if (!docShellElement) |
|
329 return NS_ERROR_FAILURE; |
|
330 |
|
331 nsAutoString persistString; |
|
332 docShellElement->GetAttribute(NS_LITERAL_STRING("persist"), persistString); |
|
333 |
|
334 bool saveString = false; |
|
335 int32_t index; |
|
336 |
|
337 // Set X |
|
338 index = persistString.Find("screenX"); |
|
339 if (!aPersistPosition && index >= 0) { |
|
340 persistString.Cut(index, 7); |
|
341 saveString = true; |
|
342 } else if (aPersistPosition && index < 0) { |
|
343 persistString.AppendLiteral(" screenX"); |
|
344 saveString = true; |
|
345 } |
|
346 // Set Y |
|
347 index = persistString.Find("screenY"); |
|
348 if (!aPersistPosition && index >= 0) { |
|
349 persistString.Cut(index, 7); |
|
350 saveString = true; |
|
351 } else if (aPersistPosition && index < 0) { |
|
352 persistString.AppendLiteral(" screenY"); |
|
353 saveString = true; |
|
354 } |
|
355 // Set CX |
|
356 index = persistString.Find("width"); |
|
357 if (!aPersistSize && index >= 0) { |
|
358 persistString.Cut(index, 5); |
|
359 saveString = true; |
|
360 } else if (aPersistSize && index < 0) { |
|
361 persistString.AppendLiteral(" width"); |
|
362 saveString = true; |
|
363 } |
|
364 // Set CY |
|
365 index = persistString.Find("height"); |
|
366 if (!aPersistSize && index >= 0) { |
|
367 persistString.Cut(index, 6); |
|
368 saveString = true; |
|
369 } else if (aPersistSize && index < 0) { |
|
370 persistString.AppendLiteral(" height"); |
|
371 saveString = true; |
|
372 } |
|
373 // Set SizeMode |
|
374 index = persistString.Find("sizemode"); |
|
375 if (!aPersistSizeMode && (index >= 0)) { |
|
376 persistString.Cut(index, 8); |
|
377 saveString = true; |
|
378 } else if (aPersistSizeMode && (index < 0)) { |
|
379 persistString.AppendLiteral(" sizemode"); |
|
380 saveString = true; |
|
381 } |
|
382 |
|
383 ErrorResult rv; |
|
384 if(saveString) { |
|
385 docShellElement->SetAttribute(NS_LITERAL_STRING("persist"), persistString, rv); |
|
386 } |
|
387 |
|
388 return NS_OK; |
|
389 } |
|
390 |
|
391 NS_IMETHODIMP |
|
392 nsContentTreeOwner::GetPersistence(bool* aPersistPosition, |
|
393 bool* aPersistSize, |
|
394 bool* aPersistSizeMode) |
|
395 { |
|
396 NS_ENSURE_STATE(mXULWindow); |
|
397 nsCOMPtr<dom::Element> docShellElement = mXULWindow->GetWindowDOMElement(); |
|
398 if (!docShellElement) |
|
399 return NS_ERROR_FAILURE; |
|
400 |
|
401 nsAutoString persistString; |
|
402 docShellElement->GetAttribute(NS_LITERAL_STRING("persist"), persistString); |
|
403 |
|
404 // data structure doesn't quite match the question, but it's close enough |
|
405 // for what we want (since this method is never actually called...) |
|
406 if (aPersistPosition) |
|
407 *aPersistPosition = persistString.Find("screenX") >= 0 || persistString.Find("screenY") >= 0 ? true : false; |
|
408 if (aPersistSize) |
|
409 *aPersistSize = persistString.Find("width") >= 0 || persistString.Find("height") >= 0 ? true : false; |
|
410 if (aPersistSizeMode) |
|
411 *aPersistSizeMode = persistString.Find("sizemode") >= 0 ? true : false; |
|
412 |
|
413 return NS_OK; |
|
414 } |
|
415 |
|
416 NS_IMETHODIMP |
|
417 nsContentTreeOwner::GetTargetableShellCount(uint32_t* aResult) |
|
418 { |
|
419 NS_ENSURE_STATE(mXULWindow); |
|
420 *aResult = mXULWindow->mTargetableShells.Count(); |
|
421 return NS_OK; |
|
422 } |
|
423 |
|
424 //***************************************************************************** |
|
425 // nsContentTreeOwner::nsIWebBrowserChrome3 |
|
426 //***************************************************************************** |
|
427 |
|
428 NS_IMETHODIMP nsContentTreeOwner::OnBeforeLinkTraversal(const nsAString &originalTarget, |
|
429 nsIURI *linkURI, |
|
430 nsIDOMNode *linkNode, |
|
431 bool isAppTab, |
|
432 nsAString &_retval) |
|
433 { |
|
434 NS_ENSURE_STATE(mXULWindow); |
|
435 |
|
436 nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow; |
|
437 mXULWindow->GetXULBrowserWindow(getter_AddRefs(xulBrowserWindow)); |
|
438 |
|
439 if (xulBrowserWindow) |
|
440 return xulBrowserWindow->OnBeforeLinkTraversal(originalTarget, linkURI, |
|
441 linkNode, isAppTab, _retval); |
|
442 |
|
443 _retval = originalTarget; |
|
444 return NS_OK; |
|
445 } |
|
446 |
|
447 //***************************************************************************** |
|
448 // nsContentTreeOwner::nsIWebBrowserChrome2 |
|
449 //***************************************************************************** |
|
450 |
|
451 NS_IMETHODIMP nsContentTreeOwner::SetStatusWithContext(uint32_t aStatusType, |
|
452 const nsAString &aStatusText, |
|
453 nsISupports *aStatusContext) |
|
454 { |
|
455 // We only allow the status to be set from the primary content shell |
|
456 if (!mPrimary && aStatusType != STATUS_LINK) |
|
457 return NS_OK; |
|
458 |
|
459 NS_ENSURE_STATE(mXULWindow); |
|
460 |
|
461 nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow; |
|
462 mXULWindow->GetXULBrowserWindow(getter_AddRefs(xulBrowserWindow)); |
|
463 |
|
464 if (xulBrowserWindow) |
|
465 { |
|
466 switch(aStatusType) |
|
467 { |
|
468 case STATUS_SCRIPT: |
|
469 xulBrowserWindow->SetJSStatus(aStatusText); |
|
470 break; |
|
471 case STATUS_LINK: |
|
472 { |
|
473 nsCOMPtr<nsIDOMElement> element = do_QueryInterface(aStatusContext); |
|
474 xulBrowserWindow->SetOverLink(aStatusText, element); |
|
475 break; |
|
476 } |
|
477 } |
|
478 } |
|
479 |
|
480 return NS_OK; |
|
481 } |
|
482 |
|
483 //***************************************************************************** |
|
484 // nsContentTreeOwner::nsIWebBrowserChrome |
|
485 //***************************************************************************** |
|
486 |
|
487 NS_IMETHODIMP nsContentTreeOwner::SetStatus(uint32_t aStatusType, |
|
488 const char16_t* aStatus) |
|
489 { |
|
490 return SetStatusWithContext(aStatusType, |
|
491 aStatus ? static_cast<const nsString &>(nsDependentString(aStatus)) |
|
492 : EmptyString(), |
|
493 nullptr); |
|
494 } |
|
495 |
|
496 NS_IMETHODIMP nsContentTreeOwner::SetWebBrowser(nsIWebBrowser* aWebBrowser) |
|
497 { |
|
498 NS_ERROR("Haven't Implemented this yet"); |
|
499 return NS_ERROR_FAILURE; |
|
500 } |
|
501 |
|
502 NS_IMETHODIMP nsContentTreeOwner::GetWebBrowser(nsIWebBrowser** aWebBrowser) |
|
503 { |
|
504 // Unimplemented, and probably will remain so; xpfe windows have docshells, |
|
505 // not webbrowsers. |
|
506 NS_ENSURE_ARG_POINTER(aWebBrowser); |
|
507 *aWebBrowser = 0; |
|
508 return NS_ERROR_FAILURE; |
|
509 } |
|
510 |
|
511 NS_IMETHODIMP nsContentTreeOwner::SetChromeFlags(uint32_t aChromeFlags) |
|
512 { |
|
513 NS_ENSURE_STATE(mXULWindow); |
|
514 return mXULWindow->SetChromeFlags(aChromeFlags); |
|
515 } |
|
516 |
|
517 NS_IMETHODIMP nsContentTreeOwner::GetChromeFlags(uint32_t* aChromeFlags) |
|
518 { |
|
519 NS_ENSURE_STATE(mXULWindow); |
|
520 return mXULWindow->GetChromeFlags(aChromeFlags); |
|
521 } |
|
522 |
|
523 NS_IMETHODIMP nsContentTreeOwner::DestroyBrowserWindow() |
|
524 { |
|
525 NS_ERROR("Haven't Implemented this yet"); |
|
526 return NS_ERROR_FAILURE; |
|
527 } |
|
528 |
|
529 NS_IMETHODIMP nsContentTreeOwner::SizeBrowserTo(int32_t aCX, int32_t aCY) |
|
530 { |
|
531 NS_ERROR("Haven't Implemented this yet"); |
|
532 return NS_ERROR_FAILURE; |
|
533 } |
|
534 |
|
535 NS_IMETHODIMP nsContentTreeOwner::ShowAsModal() |
|
536 { |
|
537 NS_ENSURE_STATE(mXULWindow); |
|
538 return mXULWindow->ShowModal(); |
|
539 } |
|
540 |
|
541 NS_IMETHODIMP nsContentTreeOwner::IsWindowModal(bool *_retval) |
|
542 { |
|
543 NS_ENSURE_STATE(mXULWindow); |
|
544 *_retval = mXULWindow->mContinueModalLoop; |
|
545 return NS_OK; |
|
546 } |
|
547 |
|
548 NS_IMETHODIMP nsContentTreeOwner::ExitModalEventLoop(nsresult aStatus) |
|
549 { |
|
550 NS_ENSURE_STATE(mXULWindow); |
|
551 return mXULWindow->ExitModalLoop(aStatus); |
|
552 } |
|
553 |
|
554 //***************************************************************************** |
|
555 // nsContentTreeOwner::nsIBaseWindow |
|
556 //***************************************************************************** |
|
557 |
|
558 NS_IMETHODIMP nsContentTreeOwner::InitWindow(nativeWindow aParentNativeWindow, |
|
559 nsIWidget* parentWidget, int32_t x, int32_t y, int32_t cx, int32_t cy) |
|
560 { |
|
561 // Ignore wigdet parents for now. Don't think those are a vaild thing to call. |
|
562 NS_ENSURE_SUCCESS(SetPositionAndSize(x, y, cx, cy, false), NS_ERROR_FAILURE); |
|
563 |
|
564 return NS_OK; |
|
565 } |
|
566 |
|
567 NS_IMETHODIMP nsContentTreeOwner::Create() |
|
568 { |
|
569 NS_ASSERTION(false, "You can't call this"); |
|
570 return NS_ERROR_UNEXPECTED; |
|
571 } |
|
572 |
|
573 NS_IMETHODIMP nsContentTreeOwner::Destroy() |
|
574 { |
|
575 NS_ENSURE_STATE(mXULWindow); |
|
576 return mXULWindow->Destroy(); |
|
577 } |
|
578 |
|
579 NS_IMETHODIMP nsContentTreeOwner::GetUnscaledDevicePixelsPerCSSPixel(double* aScale) |
|
580 { |
|
581 NS_ENSURE_STATE(mXULWindow); |
|
582 return mXULWindow->GetUnscaledDevicePixelsPerCSSPixel(aScale); |
|
583 } |
|
584 |
|
585 NS_IMETHODIMP nsContentTreeOwner::SetPosition(int32_t aX, int32_t aY) |
|
586 { |
|
587 NS_ENSURE_STATE(mXULWindow); |
|
588 return mXULWindow->SetPosition(aX, aY); |
|
589 } |
|
590 |
|
591 NS_IMETHODIMP nsContentTreeOwner::GetPosition(int32_t* aX, int32_t* aY) |
|
592 { |
|
593 NS_ENSURE_STATE(mXULWindow); |
|
594 return mXULWindow->GetPosition(aX, aY); |
|
595 } |
|
596 |
|
597 NS_IMETHODIMP nsContentTreeOwner::SetSize(int32_t aCX, int32_t aCY, bool aRepaint) |
|
598 { |
|
599 NS_ENSURE_STATE(mXULWindow); |
|
600 return mXULWindow->SetSize(aCX, aCY, aRepaint); |
|
601 } |
|
602 |
|
603 NS_IMETHODIMP nsContentTreeOwner::GetSize(int32_t* aCX, int32_t* aCY) |
|
604 { |
|
605 NS_ENSURE_STATE(mXULWindow); |
|
606 return mXULWindow->GetSize(aCX, aCY); |
|
607 } |
|
608 |
|
609 NS_IMETHODIMP nsContentTreeOwner::SetPositionAndSize(int32_t aX, int32_t aY, |
|
610 int32_t aCX, int32_t aCY, bool aRepaint) |
|
611 { |
|
612 NS_ENSURE_STATE(mXULWindow); |
|
613 return mXULWindow->SetPositionAndSize(aX, aY, aCX, aCY, aRepaint); |
|
614 } |
|
615 |
|
616 NS_IMETHODIMP nsContentTreeOwner::GetPositionAndSize(int32_t* aX, int32_t* aY, |
|
617 int32_t* aCX, int32_t* aCY) |
|
618 { |
|
619 NS_ENSURE_STATE(mXULWindow); |
|
620 return mXULWindow->GetPositionAndSize(aX, aY, aCX, aCY); |
|
621 } |
|
622 |
|
623 NS_IMETHODIMP nsContentTreeOwner::Repaint(bool aForce) |
|
624 { |
|
625 NS_ENSURE_STATE(mXULWindow); |
|
626 return mXULWindow->Repaint(aForce); |
|
627 } |
|
628 |
|
629 NS_IMETHODIMP nsContentTreeOwner::GetParentWidget(nsIWidget** aParentWidget) |
|
630 { |
|
631 NS_ENSURE_STATE(mXULWindow); |
|
632 return mXULWindow->GetParentWidget(aParentWidget); |
|
633 } |
|
634 |
|
635 NS_IMETHODIMP nsContentTreeOwner::SetParentWidget(nsIWidget* aParentWidget) |
|
636 { |
|
637 NS_ASSERTION(false, "You can't call this"); |
|
638 return NS_ERROR_NOT_IMPLEMENTED; |
|
639 } |
|
640 |
|
641 NS_IMETHODIMP nsContentTreeOwner::GetParentNativeWindow(nativeWindow* aParentNativeWindow) |
|
642 { |
|
643 NS_ENSURE_STATE(mXULWindow); |
|
644 return mXULWindow->GetParentNativeWindow(aParentNativeWindow); |
|
645 } |
|
646 |
|
647 NS_IMETHODIMP nsContentTreeOwner::SetParentNativeWindow(nativeWindow aParentNativeWindow) |
|
648 { |
|
649 NS_ASSERTION(false, "You can't call this"); |
|
650 return NS_ERROR_NOT_IMPLEMENTED; |
|
651 } |
|
652 |
|
653 NS_IMETHODIMP nsContentTreeOwner::GetNativeHandle(nsAString& aNativeHandle) |
|
654 { |
|
655 NS_ENSURE_STATE(mXULWindow); |
|
656 return mXULWindow->GetNativeHandle(aNativeHandle); |
|
657 } |
|
658 |
|
659 NS_IMETHODIMP nsContentTreeOwner::GetVisibility(bool* aVisibility) |
|
660 { |
|
661 NS_ENSURE_STATE(mXULWindow); |
|
662 return mXULWindow->GetVisibility(aVisibility); |
|
663 } |
|
664 |
|
665 NS_IMETHODIMP nsContentTreeOwner::SetVisibility(bool aVisibility) |
|
666 { |
|
667 NS_ENSURE_STATE(mXULWindow); |
|
668 return mXULWindow->SetVisibility(aVisibility); |
|
669 } |
|
670 |
|
671 NS_IMETHODIMP nsContentTreeOwner::GetEnabled(bool *aEnabled) |
|
672 { |
|
673 NS_ENSURE_STATE(mXULWindow); |
|
674 return mXULWindow->GetEnabled(aEnabled); |
|
675 } |
|
676 |
|
677 NS_IMETHODIMP nsContentTreeOwner::SetEnabled(bool aEnable) |
|
678 { |
|
679 NS_ENSURE_STATE(mXULWindow); |
|
680 return mXULWindow->SetEnabled(aEnable); |
|
681 } |
|
682 |
|
683 NS_IMETHODIMP nsContentTreeOwner::GetMainWidget(nsIWidget** aMainWidget) |
|
684 { |
|
685 NS_ENSURE_ARG_POINTER(aMainWidget); |
|
686 NS_ENSURE_STATE(mXULWindow); |
|
687 |
|
688 *aMainWidget = mXULWindow->mWindow; |
|
689 NS_IF_ADDREF(*aMainWidget); |
|
690 |
|
691 return NS_OK; |
|
692 } |
|
693 |
|
694 NS_IMETHODIMP nsContentTreeOwner::SetFocus() |
|
695 { |
|
696 NS_ENSURE_STATE(mXULWindow); |
|
697 return mXULWindow->SetFocus(); |
|
698 } |
|
699 |
|
700 NS_IMETHODIMP nsContentTreeOwner::GetTitle(char16_t** aTitle) |
|
701 { |
|
702 NS_ENSURE_ARG_POINTER(aTitle); |
|
703 NS_ENSURE_STATE(mXULWindow); |
|
704 |
|
705 return mXULWindow->GetTitle(aTitle); |
|
706 } |
|
707 |
|
708 NS_IMETHODIMP nsContentTreeOwner::SetTitle(const char16_t* aTitle) |
|
709 { |
|
710 // We only allow the title to be set from the primary content shell |
|
711 if(!mPrimary || !mContentTitleSetting) |
|
712 return NS_OK; |
|
713 |
|
714 NS_ENSURE_STATE(mXULWindow); |
|
715 |
|
716 nsAutoString title; |
|
717 nsAutoString docTitle(aTitle); |
|
718 |
|
719 if (docTitle.IsEmpty()) |
|
720 docTitle.Assign(mTitleDefault); |
|
721 |
|
722 if (!docTitle.IsEmpty()) { |
|
723 if (!mTitlePreface.IsEmpty()) { |
|
724 // Title will be: "Preface: Doc Title - Mozilla" |
|
725 title.Assign(mTitlePreface); |
|
726 title.Append(docTitle); |
|
727 } |
|
728 else { |
|
729 // Title will be: "Doc Title - Mozilla" |
|
730 title = docTitle; |
|
731 } |
|
732 |
|
733 if (!mWindowTitleModifier.IsEmpty()) |
|
734 title += mTitleSeparator + mWindowTitleModifier; |
|
735 } |
|
736 else |
|
737 title.Assign(mWindowTitleModifier); // Title will just be plain "Mozilla" |
|
738 |
|
739 // |
|
740 // if there is no location bar we modify the title to display at least |
|
741 // the scheme and host (if any) as an anti-spoofing measure. |
|
742 // |
|
743 nsCOMPtr<dom::Element> docShellElement = mXULWindow->GetWindowDOMElement(); |
|
744 |
|
745 if (docShellElement) { |
|
746 nsAutoString chromeString; |
|
747 docShellElement->GetAttribute(NS_LITERAL_STRING("chromehidden"), chromeString); |
|
748 if (chromeString.Find(NS_LITERAL_STRING("location")) != kNotFound) { |
|
749 // |
|
750 // location bar is turned off, find the browser location |
|
751 // |
|
752 // use the document's nsPrincipal to find the true owner |
|
753 // in case of javascript: or data: documents |
|
754 // |
|
755 nsCOMPtr<nsIDocShellTreeItem> dsitem; |
|
756 GetPrimaryContentShell(getter_AddRefs(dsitem)); |
|
757 nsCOMPtr<nsIDOMDocument> domdoc(do_GetInterface(dsitem)); |
|
758 nsCOMPtr<nsIScriptObjectPrincipal> doc(do_QueryInterface(domdoc)); |
|
759 if (doc) { |
|
760 nsCOMPtr<nsIURI> uri; |
|
761 nsIPrincipal* principal = doc->GetPrincipal(); |
|
762 if (principal) { |
|
763 principal->GetURI(getter_AddRefs(uri)); |
|
764 if (uri) { |
|
765 // |
|
766 // remove any user:pass information |
|
767 // |
|
768 nsCOMPtr<nsIURIFixup> fixup(do_GetService(NS_URIFIXUP_CONTRACTID)); |
|
769 if (fixup) { |
|
770 nsCOMPtr<nsIURI> tmpuri; |
|
771 nsresult rv = fixup->CreateExposableURI(uri,getter_AddRefs(tmpuri)); |
|
772 if (NS_SUCCEEDED(rv) && tmpuri) { |
|
773 // (don't bother if there's no host) |
|
774 nsAutoCString host; |
|
775 nsAutoCString prepath; |
|
776 tmpuri->GetHost(host); |
|
777 tmpuri->GetPrePath(prepath); |
|
778 if (!host.IsEmpty()) { |
|
779 // |
|
780 // We have a scheme/host, update the title |
|
781 // |
|
782 title.Insert(NS_ConvertUTF8toUTF16(prepath) + |
|
783 mTitleSeparator, 0); |
|
784 } |
|
785 } |
|
786 } |
|
787 } |
|
788 } |
|
789 } |
|
790 } |
|
791 nsIDocument* document = docShellElement->OwnerDoc(); |
|
792 ErrorResult rv; |
|
793 document->SetTitle(title, rv); |
|
794 return rv.ErrorCode(); |
|
795 } |
|
796 |
|
797 return mXULWindow->SetTitle(title.get()); |
|
798 } |
|
799 |
|
800 //***************************************************************************** |
|
801 // nsContentTreeOwner: nsIWindowProvider |
|
802 //***************************************************************************** |
|
803 NS_IMETHODIMP |
|
804 nsContentTreeOwner::ProvideWindow(nsIDOMWindow* aParent, |
|
805 uint32_t aChromeFlags, |
|
806 bool aCalledFromJS, |
|
807 bool aPositionSpecified, |
|
808 bool aSizeSpecified, |
|
809 nsIURI* aURI, |
|
810 const nsAString& aName, |
|
811 const nsACString& aFeatures, |
|
812 bool* aWindowIsNew, |
|
813 nsIDOMWindow** aReturn) |
|
814 { |
|
815 NS_ENSURE_ARG_POINTER(aParent); |
|
816 |
|
817 *aReturn = nullptr; |
|
818 |
|
819 if (!mXULWindow) { |
|
820 // Nothing to do here |
|
821 return NS_OK; |
|
822 } |
|
823 |
|
824 #ifdef DEBUG |
|
825 nsCOMPtr<nsIWebNavigation> parentNav = do_GetInterface(aParent); |
|
826 nsCOMPtr<nsIDocShellTreeOwner> parentOwner = do_GetInterface(parentNav); |
|
827 NS_ASSERTION(SameCOMIdentity(parentOwner, |
|
828 static_cast<nsIDocShellTreeOwner*>(this)), |
|
829 "Parent from wrong docshell tree?"); |
|
830 #endif |
|
831 |
|
832 // If aParent is inside an <iframe mozbrowser> and this isn't a request to |
|
833 // open a modal-type window, we're going to create a new <iframe mozbrowser> |
|
834 // and return its window here. |
|
835 nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent); |
|
836 if (docshell && docshell->GetIsInBrowserOrApp() && |
|
837 !(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL | |
|
838 nsIWebBrowserChrome::CHROME_OPENAS_DIALOG | |
|
839 nsIWebBrowserChrome::CHROME_OPENAS_CHROME))) { |
|
840 |
|
841 BrowserElementParent::OpenWindowResult opened = |
|
842 BrowserElementParent::OpenWindowInProcess(aParent, aURI, aName, |
|
843 aFeatures, aReturn); |
|
844 |
|
845 // If OpenWindowInProcess handled the open (by opening it or blocking the |
|
846 // popup), tell our caller not to proceed trying to create a new window |
|
847 // through other means. |
|
848 if (opened != BrowserElementParent::OPEN_WINDOW_IGNORED) { |
|
849 *aWindowIsNew = opened == BrowserElementParent::OPEN_WINDOW_ADDED; |
|
850 return *aWindowIsNew ? NS_OK : NS_ERROR_ABORT; |
|
851 } |
|
852 |
|
853 // If we're in an app and the target is _blank, send the url to the OS |
|
854 if (aName.LowerCaseEqualsLiteral("_blank")) { |
|
855 nsCOMPtr<nsIExternalURLHandlerService> exUrlServ( |
|
856 do_GetService(NS_EXTERNALURLHANDLERSERVICE_CONTRACTID)); |
|
857 if (exUrlServ) { |
|
858 |
|
859 nsCOMPtr<nsIHandlerInfo> info; |
|
860 bool found; |
|
861 exUrlServ->GetURLHandlerInfoFromOS(aURI, &found, getter_AddRefs(info)); |
|
862 |
|
863 if (info && found) { |
|
864 info->LaunchWithURI(aURI, nullptr); |
|
865 return NS_ERROR_ABORT; |
|
866 } |
|
867 |
|
868 } |
|
869 } |
|
870 } |
|
871 |
|
872 // the parent window is fullscreen mode or not. |
|
873 bool isFullScreen = false; |
|
874 if (aParent) { |
|
875 aParent->GetFullScreen(&isFullScreen); |
|
876 } |
|
877 |
|
878 // Where should we open this? |
|
879 int32_t containerPref; |
|
880 if (NS_FAILED(Preferences::GetInt("browser.link.open_newwindow", |
|
881 &containerPref))) { |
|
882 return NS_OK; |
|
883 } |
|
884 |
|
885 bool isDisabledOpenNewWindow = |
|
886 isFullScreen && |
|
887 Preferences::GetBool("browser.link.open_newwindow.disabled_in_fullscreen"); |
|
888 |
|
889 if (isDisabledOpenNewWindow && (containerPref == nsIBrowserDOMWindow::OPEN_NEWWINDOW)) { |
|
890 containerPref = nsIBrowserDOMWindow::OPEN_NEWTAB; |
|
891 } |
|
892 |
|
893 if (containerPref != nsIBrowserDOMWindow::OPEN_NEWTAB && |
|
894 containerPref != nsIBrowserDOMWindow::OPEN_CURRENTWINDOW) { |
|
895 // Just open a window normally |
|
896 return NS_OK; |
|
897 } |
|
898 |
|
899 if (aCalledFromJS) { |
|
900 /* Now check our restriction pref. The restriction pref is a power-user's |
|
901 fine-tuning pref. values: |
|
902 0: no restrictions - divert everything |
|
903 1: don't divert window.open at all |
|
904 2: don't divert window.open with features |
|
905 */ |
|
906 int32_t restrictionPref = |
|
907 Preferences::GetInt("browser.link.open_newwindow.restriction", 2); |
|
908 if (restrictionPref < 0 || restrictionPref > 2) { |
|
909 restrictionPref = 2; // Sane default behavior |
|
910 } |
|
911 |
|
912 if (isDisabledOpenNewWindow) { |
|
913 // In browser fullscreen, the window should be opened |
|
914 // in the current window with no features (see bug 803675) |
|
915 restrictionPref = 0; |
|
916 } |
|
917 |
|
918 if (restrictionPref == 1) { |
|
919 return NS_OK; |
|
920 } |
|
921 |
|
922 if (restrictionPref == 2 && |
|
923 // Only continue if there are no size/position features and no special |
|
924 // chrome flags. |
|
925 (aChromeFlags != nsIWebBrowserChrome::CHROME_ALL || |
|
926 aPositionSpecified || aSizeSpecified)) { |
|
927 return NS_OK; |
|
928 } |
|
929 } |
|
930 |
|
931 nsCOMPtr<nsIDOMWindow> domWin; |
|
932 mXULWindow->GetWindowDOMWindow(getter_AddRefs(domWin)); |
|
933 nsCOMPtr<nsIDOMChromeWindow> chromeWin = do_QueryInterface(domWin); |
|
934 if (!chromeWin) { |
|
935 // Really odd... but whatever |
|
936 NS_WARNING("nsXULWindow's DOMWindow is not a chrome window"); |
|
937 return NS_OK; |
|
938 } |
|
939 |
|
940 nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin; |
|
941 chromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin)); |
|
942 if (!browserDOMWin) { |
|
943 return NS_OK; |
|
944 } |
|
945 |
|
946 *aWindowIsNew = (containerPref != nsIBrowserDOMWindow::OPEN_CURRENTWINDOW); |
|
947 |
|
948 { |
|
949 dom::AutoNoJSAPI nojsapi; |
|
950 |
|
951 // Get a new rendering area from the browserDOMWin. We don't want |
|
952 // to be starting any loads here, so get it with a null URI. |
|
953 return browserDOMWin->OpenURI(nullptr, aParent, containerPref, |
|
954 nsIBrowserDOMWindow::OPEN_NEW, aReturn); |
|
955 } |
|
956 } |
|
957 |
|
958 //***************************************************************************** |
|
959 // nsContentTreeOwner: Accessors |
|
960 //***************************************************************************** |
|
961 |
|
962 #if defined(XP_MACOSX) |
|
963 class nsContentTitleSettingEvent : public nsRunnable |
|
964 { |
|
965 public: |
|
966 nsContentTitleSettingEvent(dom::Element* dse, const nsAString& wtm) |
|
967 : mElement(dse), |
|
968 mTitleDefault(wtm) {} |
|
969 |
|
970 NS_IMETHOD Run() |
|
971 { |
|
972 ErrorResult rv; |
|
973 mElement->SetAttribute(NS_LITERAL_STRING("titledefault"), mTitleDefault, rv); |
|
974 mElement->RemoveAttribute(NS_LITERAL_STRING("titlemodifier"), rv); |
|
975 return NS_OK; |
|
976 } |
|
977 |
|
978 private: |
|
979 nsCOMPtr<dom::Element> mElement; |
|
980 nsString mTitleDefault; |
|
981 }; |
|
982 #endif |
|
983 |
|
984 void nsContentTreeOwner::XULWindow(nsXULWindow* aXULWindow) |
|
985 { |
|
986 mXULWindow = aXULWindow; |
|
987 if (mXULWindow && mPrimary) { |
|
988 // Get the window title modifiers |
|
989 nsCOMPtr<dom::Element> docShellElement = mXULWindow->GetWindowDOMElement(); |
|
990 |
|
991 nsAutoString contentTitleSetting; |
|
992 |
|
993 if(docShellElement) |
|
994 { |
|
995 docShellElement->GetAttribute(NS_LITERAL_STRING("contenttitlesetting"), contentTitleSetting); |
|
996 if(contentTitleSetting.EqualsLiteral("true")) |
|
997 { |
|
998 mContentTitleSetting = true; |
|
999 docShellElement->GetAttribute(NS_LITERAL_STRING("titledefault"), mTitleDefault); |
|
1000 docShellElement->GetAttribute(NS_LITERAL_STRING("titlemodifier"), mWindowTitleModifier); |
|
1001 docShellElement->GetAttribute(NS_LITERAL_STRING("titlepreface"), mTitlePreface); |
|
1002 |
|
1003 #if defined(XP_MACOSX) |
|
1004 // On OS X, treat the titlemodifier like it's the titledefault, and don't ever append |
|
1005 // the separator + appname. |
|
1006 if (mTitleDefault.IsEmpty()) { |
|
1007 NS_DispatchToCurrentThread( |
|
1008 new nsContentTitleSettingEvent(docShellElement, |
|
1009 mWindowTitleModifier)); |
|
1010 mTitleDefault = mWindowTitleModifier; |
|
1011 mWindowTitleModifier.Truncate(); |
|
1012 } |
|
1013 #endif |
|
1014 docShellElement->GetAttribute(NS_LITERAL_STRING("titlemenuseparator"), mTitleSeparator); |
|
1015 } |
|
1016 } |
|
1017 else |
|
1018 { |
|
1019 NS_ERROR("This condition should never happen. If it does, " |
|
1020 "we just won't get a modifier, but it still shouldn't happen."); |
|
1021 } |
|
1022 } |
|
1023 } |
|
1024 |
|
1025 nsXULWindow* nsContentTreeOwner::XULWindow() |
|
1026 { |
|
1027 return mXULWindow; |
|
1028 } |
|
1029 |
|
1030 //***************************************************************************** |
|
1031 //*** nsSiteWindow implementation |
|
1032 //***************************************************************************** |
|
1033 |
|
1034 nsSiteWindow::nsSiteWindow(nsContentTreeOwner *aAggregator) |
|
1035 { |
|
1036 mAggregator = aAggregator; |
|
1037 } |
|
1038 |
|
1039 nsSiteWindow::~nsSiteWindow() |
|
1040 { |
|
1041 } |
|
1042 |
|
1043 NS_IMPL_ADDREF_USING_AGGREGATOR(nsSiteWindow, mAggregator) |
|
1044 NS_IMPL_RELEASE_USING_AGGREGATOR(nsSiteWindow, mAggregator) |
|
1045 |
|
1046 NS_INTERFACE_MAP_BEGIN(nsSiteWindow) |
|
1047 NS_INTERFACE_MAP_ENTRY(nsISupports) |
|
1048 NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow) |
|
1049 NS_INTERFACE_MAP_END_AGGREGATED(mAggregator) |
|
1050 |
|
1051 NS_IMETHODIMP |
|
1052 nsSiteWindow::SetDimensions(uint32_t aFlags, |
|
1053 int32_t aX, int32_t aY, int32_t aCX, int32_t aCY) |
|
1054 { |
|
1055 // XXX we're ignoring aFlags |
|
1056 return mAggregator->SetPositionAndSize(aX, aY, aCX, aCY, true); |
|
1057 } |
|
1058 |
|
1059 NS_IMETHODIMP |
|
1060 nsSiteWindow::GetDimensions(uint32_t aFlags, |
|
1061 int32_t *aX, int32_t *aY, int32_t *aCX, int32_t *aCY) |
|
1062 { |
|
1063 // XXX we're ignoring aFlags |
|
1064 return mAggregator->GetPositionAndSize(aX, aY, aCX, aCY); |
|
1065 } |
|
1066 |
|
1067 NS_IMETHODIMP |
|
1068 nsSiteWindow::SetFocus(void) |
|
1069 { |
|
1070 #if 0 |
|
1071 /* This implementation focuses the main document and could make sense. |
|
1072 However this method is actually being used from within |
|
1073 nsGlobalWindow::Focus (providing a hook for MDI embedding apps) |
|
1074 and it's better for our purposes to not pick a document and |
|
1075 focus it, but allow nsGlobalWindow to carry on unhindered. |
|
1076 */ |
|
1077 nsXULWindow *window = mAggregator->XULWindow(); |
|
1078 if (window) { |
|
1079 nsCOMPtr<nsIDocShell> docshell; |
|
1080 window->GetDocShell(getter_AddRefs(docshell)); |
|
1081 nsCOMPtr<nsIDOMWindow> domWindow(do_GetInterface(docshell)); |
|
1082 if (domWindow) |
|
1083 domWindow->Focus(); |
|
1084 } |
|
1085 #endif |
|
1086 return NS_OK; |
|
1087 } |
|
1088 |
|
1089 /* this implementation focuses another window. if there isn't another |
|
1090 window to focus, we do nothing. */ |
|
1091 NS_IMETHODIMP |
|
1092 nsSiteWindow::Blur(void) |
|
1093 { |
|
1094 NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID); |
|
1095 |
|
1096 nsCOMPtr<nsISimpleEnumerator> windowEnumerator; |
|
1097 nsCOMPtr<nsIXULWindow> xulWindow; |
|
1098 bool more, foundUs; |
|
1099 nsXULWindow *ourWindow = mAggregator->XULWindow(); |
|
1100 |
|
1101 { |
|
1102 nsCOMPtr<nsIWindowMediator> windowMediator(do_GetService(kWindowMediatorCID)); |
|
1103 if (windowMediator) |
|
1104 windowMediator->GetZOrderXULWindowEnumerator(0, true, |
|
1105 getter_AddRefs(windowEnumerator)); |
|
1106 } |
|
1107 |
|
1108 if (!windowEnumerator) |
|
1109 return NS_ERROR_FAILURE; |
|
1110 |
|
1111 // step through the top-level windows |
|
1112 foundUs = false; |
|
1113 windowEnumerator->HasMoreElements(&more); |
|
1114 while (more) { |
|
1115 |
|
1116 nsCOMPtr<nsISupports> nextWindow; |
|
1117 nsCOMPtr<nsIXULWindow> nextXULWindow; |
|
1118 |
|
1119 windowEnumerator->GetNext(getter_AddRefs(nextWindow)); |
|
1120 nextXULWindow = do_QueryInterface(nextWindow); |
|
1121 |
|
1122 // got it!(?) |
|
1123 if (foundUs) { |
|
1124 xulWindow = nextXULWindow; |
|
1125 break; |
|
1126 } |
|
1127 |
|
1128 // remember the very first one, in case we have to wrap |
|
1129 if (!xulWindow) |
|
1130 xulWindow = nextXULWindow; |
|
1131 |
|
1132 // look for us |
|
1133 if (nextXULWindow == ourWindow) |
|
1134 foundUs = true; |
|
1135 |
|
1136 windowEnumerator->HasMoreElements(&more); |
|
1137 } |
|
1138 |
|
1139 // change focus to the window we just found |
|
1140 if (xulWindow) { |
|
1141 nsCOMPtr<nsIDocShell> docshell; |
|
1142 xulWindow->GetDocShell(getter_AddRefs(docshell)); |
|
1143 nsCOMPtr<nsIDOMWindow> domWindow(do_GetInterface(docshell)); |
|
1144 if (domWindow) |
|
1145 domWindow->Focus(); |
|
1146 } |
|
1147 return NS_OK; |
|
1148 } |
|
1149 |
|
1150 NS_IMETHODIMP |
|
1151 nsSiteWindow::GetVisibility(bool *aVisibility) |
|
1152 { |
|
1153 return mAggregator->GetVisibility(aVisibility); |
|
1154 } |
|
1155 |
|
1156 NS_IMETHODIMP |
|
1157 nsSiteWindow::SetVisibility(bool aVisibility) |
|
1158 { |
|
1159 return mAggregator->SetVisibility(aVisibility); |
|
1160 } |
|
1161 |
|
1162 NS_IMETHODIMP |
|
1163 nsSiteWindow::GetTitle(char16_t * *aTitle) |
|
1164 { |
|
1165 return mAggregator->GetTitle(aTitle); |
|
1166 } |
|
1167 |
|
1168 NS_IMETHODIMP |
|
1169 nsSiteWindow::SetTitle(const char16_t * aTitle) |
|
1170 { |
|
1171 return mAggregator->SetTitle(aTitle); |
|
1172 } |
|
1173 |
|
1174 NS_IMETHODIMP |
|
1175 nsSiteWindow::GetSiteWindow(void **aSiteWindow) |
|
1176 { |
|
1177 return mAggregator->GetParentNativeWindow(aSiteWindow); |
|
1178 } |
|
1179 |