1 /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is the Mozilla browser.
18 * The Initial Developer of the Original Code is
19 * Netscape Communications, Inc.
20 * Portions created by the Initial Developer are Copyright (C) 1999
21 * the Initial Developer. All Rights Reserved.
24 * Travis Bogard <travis@netscape.com>
26 * Alternatively, the contents of this file may be used under the terms of
27 * either of the GNU General Public License Version 2 or later (the "GPL"),
28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
41 #include "nsChromeTreeOwner.h"
42 #include "nsXULWindow.h"
46 #include "nsIEmbeddingSiteWindow.h"
47 #include "nsIEmbeddingSiteWindow2.h"
48 #include "nsIGenericFactory.h"
49 #include "nsIServiceManager.h"
50 #include "nsIDocShellTreeItem.h"
52 // Interfaces needed to include
53 #include "nsIPrompt.h"
54 #include "nsIAuthPrompt.h"
55 #include "nsIWebProgress.h"
56 #include "nsIWindowMediator.h"
57 #include "nsIDOMNode.h"
58 #include "nsIDOMElement.h"
59 #include "nsIDOMNodeList.h"
60 #include "nsIDOMWindowInternal.h"
61 #include "nsIDOMXULElement.h"
62 #include "nsIXULBrowserWindow.h"
65 static NS_DEFINE_CID(kWindowMediatorCID
, NS_WINDOWMEDIATOR_CID
);
67 //*****************************************************************************
68 // nsChromeTreeOwner string literals
69 //*****************************************************************************
71 struct nsChromeTreeOwnerLiterals
73 const nsLiteralString kPersist
;
74 const nsLiteralString kScreenX
;
75 const nsLiteralString kScreenY
;
76 const nsLiteralString kWidth
;
77 const nsLiteralString kHeight
;
78 const nsLiteralString kSizemode
;
79 const nsLiteralString kSpace
;
81 nsChromeTreeOwnerLiterals()
82 : NS_LITERAL_STRING_INIT(kPersist
,"persist")
83 , NS_LITERAL_STRING_INIT(kScreenX
,"screenX")
84 , NS_LITERAL_STRING_INIT(kScreenY
,"screenY")
85 , NS_LITERAL_STRING_INIT(kWidth
,"width")
86 , NS_LITERAL_STRING_INIT(kHeight
,"height")
87 , NS_LITERAL_STRING_INIT(kSizemode
,"sizemode")
88 , NS_LITERAL_STRING_INIT(kSpace
," ")
92 static nsChromeTreeOwnerLiterals
*gLiterals
;
95 nsChromeTreeOwner::InitGlobals()
97 NS_ASSERTION(gLiterals
== nsnull
, "already initialized");
98 gLiterals
= new nsChromeTreeOwnerLiterals();
100 return NS_ERROR_OUT_OF_MEMORY
;
105 nsChromeTreeOwner::FreeGlobals()
111 //*****************************************************************************
112 //*** nsChromeTreeOwner: Object Management
113 //*****************************************************************************
115 nsChromeTreeOwner::nsChromeTreeOwner() : mXULWindow(nsnull
)
119 nsChromeTreeOwner::~nsChromeTreeOwner()
123 //*****************************************************************************
124 // nsChromeTreeOwner::nsISupports
125 //*****************************************************************************
127 NS_IMPL_ADDREF(nsChromeTreeOwner
)
128 NS_IMPL_RELEASE(nsChromeTreeOwner
)
130 NS_INTERFACE_MAP_BEGIN(nsChromeTreeOwner
)
131 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports
, nsIDocShellTreeOwner
)
132 NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeOwner
)
133 NS_INTERFACE_MAP_ENTRY(nsIBaseWindow
)
134 NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener
)
135 NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor
)
136 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference
)
139 //*****************************************************************************
140 // nsChromeTreeOwner::nsIInterfaceRequestor
141 //*****************************************************************************
143 NS_IMETHODIMP
nsChromeTreeOwner::GetInterface(const nsIID
& aIID
, void** aSink
)
145 NS_ENSURE_ARG_POINTER(aSink
);
147 if(aIID
.Equals(NS_GET_IID(nsIPrompt
))) {
148 NS_ENSURE_STATE(mXULWindow
);
149 return mXULWindow
->GetInterface(aIID
, aSink
);
151 if(aIID
.Equals(NS_GET_IID(nsIAuthPrompt
))) {
152 NS_ENSURE_STATE(mXULWindow
);
153 return mXULWindow
->GetInterface(aIID
, aSink
);
155 if(aIID
.Equals(NS_GET_IID(nsIWebBrowserChrome
))) {
156 NS_ENSURE_STATE(mXULWindow
);
157 return mXULWindow
->GetInterface(aIID
, aSink
);
159 if (aIID
.Equals(NS_GET_IID(nsIEmbeddingSiteWindow
))) {
160 NS_ENSURE_STATE(mXULWindow
);
161 return mXULWindow
->GetInterface(aIID
, aSink
);
163 if (aIID
.Equals(NS_GET_IID(nsIEmbeddingSiteWindow2
))) {
164 NS_ENSURE_STATE(mXULWindow
);
165 return mXULWindow
->GetInterface(aIID
, aSink
);
167 if (aIID
.Equals(NS_GET_IID(nsIXULWindow
))) {
168 NS_ENSURE_STATE(mXULWindow
);
169 return mXULWindow
->QueryInterface(aIID
, aSink
);
172 return QueryInterface(aIID
, aSink
);
175 //*****************************************************************************
176 // nsChromeTreeOwner::nsIDocShellTreeOwner
177 //*****************************************************************************
179 NS_IMETHODIMP
nsChromeTreeOwner::FindItemWithName(const PRUnichar
* aName
,
180 nsIDocShellTreeItem
* aRequestor
, nsIDocShellTreeItem
* aOriginalRequestor
,
181 nsIDocShellTreeItem
** aFoundItem
)
183 NS_ENSURE_ARG_POINTER(aFoundItem
);
185 *aFoundItem
= nsnull
;
187 PRBool fIs_Content
= PR_FALSE
;
190 if(!aName
|| !*aName
)
193 nsDependentString
name(aName
);
195 if(name
.LowerCaseEqualsLiteral("_blank"))
197 // _main is an IE target which should be case-insensitive but isn't
198 // see bug 217886 for details
199 if(name
.LowerCaseEqualsLiteral("_content") || name
.EqualsLiteral("_main"))
201 NS_ENSURE_STATE(mXULWindow
);
202 fIs_Content
= PR_TRUE
;
203 mXULWindow
->GetPrimaryContentShell(aFoundItem
);
206 // Otherwise fall through and ask the other windows for a content area.
209 nsCOMPtr
<nsIWindowMediator
> windowMediator(do_GetService(kWindowMediatorCID
));
210 NS_ENSURE_TRUE(windowMediator
, NS_ERROR_FAILURE
);
212 nsCOMPtr
<nsISimpleEnumerator
> windowEnumerator
;
213 NS_ENSURE_SUCCESS(windowMediator
->GetXULWindowEnumerator(nsnull
,
214 getter_AddRefs(windowEnumerator
)), NS_ERROR_FAILURE
);
218 windowEnumerator
->HasMoreElements(&more
);
221 nsCOMPtr
<nsISupports
> nextWindow
= nsnull
;
222 windowEnumerator
->GetNext(getter_AddRefs(nextWindow
));
223 nsCOMPtr
<nsIXULWindow
> xulWindow(do_QueryInterface(nextWindow
));
224 NS_ENSURE_TRUE(xulWindow
, NS_ERROR_FAILURE
);
226 nsCOMPtr
<nsIDocShellTreeItem
> shellAsTreeItem
;
230 xulWindow
->GetPrimaryContentShell(aFoundItem
);
234 // Note that we don't look for targetable content shells here...
235 // in fact, we aren't looking for content shells at all!
236 nsCOMPtr
<nsIDocShell
> shell
;
237 xulWindow
->GetDocShell(getter_AddRefs(shell
));
238 shellAsTreeItem
= do_QueryInterface(shell
);
239 if (shellAsTreeItem
) {
240 // Get the root tree item of same type, since roots are the only
241 // things that call into the treeowner to look for named items.
242 nsCOMPtr
<nsIDocShellTreeItem
> root
;
243 shellAsTreeItem
->GetSameTypeRootTreeItem(getter_AddRefs(root
));
244 shellAsTreeItem
= root
;
246 if(shellAsTreeItem
&& aRequestor
!= shellAsTreeItem
)
248 // Do this so we can pass in the tree owner as the requestor so the child knows not
250 nsCOMPtr
<nsIDocShellTreeOwner
> shellOwner
;
251 shellAsTreeItem
->GetTreeOwner(getter_AddRefs(shellOwner
));
252 nsCOMPtr
<nsISupports
> shellOwnerSupports(do_QueryInterface(shellOwner
));
254 shellAsTreeItem
->FindItemWithName(aName
, shellOwnerSupports
,
255 aOriginalRequestor
, aFoundItem
);
260 windowEnumerator
->HasMoreElements(&more
);
266 nsChromeTreeOwner::ContentShellAdded(nsIDocShellTreeItem
* aContentShell
,
267 PRBool aPrimary
, PRBool aTargetable
,
268 const nsAString
& aID
)
270 NS_ENSURE_STATE(mXULWindow
);
271 return mXULWindow
->ContentShellAdded(aContentShell
, aPrimary
, aTargetable
,
276 nsChromeTreeOwner::ContentShellRemoved(nsIDocShellTreeItem
* aContentShell
)
278 NS_ENSURE_STATE(mXULWindow
);
279 return mXULWindow
->ContentShellRemoved(aContentShell
);
282 NS_IMETHODIMP
nsChromeTreeOwner::GetPrimaryContentShell(nsIDocShellTreeItem
** aShell
)
284 NS_ENSURE_STATE(mXULWindow
);
285 return mXULWindow
->GetPrimaryContentShell(aShell
);
288 NS_IMETHODIMP
nsChromeTreeOwner::SizeShellTo(nsIDocShellTreeItem
* aShellItem
,
289 PRInt32 aCX
, PRInt32 aCY
)
291 NS_ENSURE_STATE(mXULWindow
);
292 return mXULWindow
->SizeShellTo(aShellItem
, aCX
, aCY
);
296 nsChromeTreeOwner::SetPersistence(PRBool aPersistPosition
,
298 PRBool aPersistSizeMode
)
300 NS_ENSURE_STATE(mXULWindow
);
301 nsCOMPtr
<nsIDOMElement
> docShellElement
;
302 mXULWindow
->GetWindowDOMElement(getter_AddRefs(docShellElement
));
303 if (!docShellElement
)
304 return NS_ERROR_FAILURE
;
306 nsAutoString persistString
;
307 docShellElement
->GetAttribute(gLiterals
->kPersist
, persistString
);
309 PRBool saveString
= PR_FALSE
;
312 #define FIND_PERSIST_STRING(aString, aCond) \
313 index = persistString.Find(aString); \
314 if (!aCond && index > kNotFound) { \
315 persistString.Cut(index, aString.Length()); \
316 saveString = PR_TRUE; \
317 } else if (aCond && index == kNotFound) { \
318 persistString.Append(gLiterals->kSpace + aString); \
319 saveString = PR_TRUE; \
321 FIND_PERSIST_STRING(gLiterals
->kScreenX
, aPersistPosition
);
322 FIND_PERSIST_STRING(gLiterals
->kScreenY
, aPersistPosition
);
323 FIND_PERSIST_STRING(gLiterals
->kWidth
, aPersistSize
);
324 FIND_PERSIST_STRING(gLiterals
->kHeight
, aPersistSize
);
325 FIND_PERSIST_STRING(gLiterals
->kSizemode
, aPersistSizeMode
);
328 docShellElement
->SetAttribute(gLiterals
->kPersist
, persistString
);
334 nsChromeTreeOwner::GetPersistence(PRBool
* aPersistPosition
,
335 PRBool
* aPersistSize
,
336 PRBool
* aPersistSizeMode
)
338 NS_ENSURE_STATE(mXULWindow
);
339 nsCOMPtr
<nsIDOMElement
> docShellElement
;
340 mXULWindow
->GetWindowDOMElement(getter_AddRefs(docShellElement
));
341 if (!docShellElement
)
342 return NS_ERROR_FAILURE
;
344 nsAutoString persistString
;
345 docShellElement
->GetAttribute(gLiterals
->kPersist
, persistString
);
347 // data structure doesn't quite match the question, but it's close enough
348 // for what we want (since this method is never actually called...)
349 if (aPersistPosition
)
350 *aPersistPosition
= persistString
.Find(gLiterals
->kScreenX
) > kNotFound
||
351 persistString
.Find(gLiterals
->kScreenY
) > kNotFound
;
353 *aPersistSize
= persistString
.Find(gLiterals
->kWidth
) > kNotFound
||
354 persistString
.Find(gLiterals
->kHeight
) > kNotFound
;
355 if (aPersistSizeMode
)
356 *aPersistSizeMode
= persistString
.Find(gLiterals
->kSizemode
) > kNotFound
;
361 //*****************************************************************************
362 // nsChromeTreeOwner::nsIBaseWindow
363 //*****************************************************************************
365 NS_IMETHODIMP
nsChromeTreeOwner::InitWindow(nativeWindow aParentNativeWindow
,
366 nsIWidget
* parentWidget
, PRInt32 x
, PRInt32 y
, PRInt32 cx
, PRInt32 cy
)
368 // Ignore widget parents for now. Don't think those are a vaild thing to call.
369 NS_ENSURE_SUCCESS(SetPositionAndSize(x
, y
, cx
, cy
, PR_FALSE
), NS_ERROR_FAILURE
);
374 NS_IMETHODIMP
nsChromeTreeOwner::Create()
376 NS_ASSERTION(PR_FALSE
, "You can't call this");
377 return NS_ERROR_UNEXPECTED
;
380 NS_IMETHODIMP
nsChromeTreeOwner::Destroy()
382 NS_ENSURE_STATE(mXULWindow
);
383 return mXULWindow
->Destroy();
386 NS_IMETHODIMP
nsChromeTreeOwner::SetPosition(PRInt32 x
, PRInt32 y
)
388 NS_ENSURE_STATE(mXULWindow
);
389 return mXULWindow
->SetPosition(x
, y
);
392 NS_IMETHODIMP
nsChromeTreeOwner::GetPosition(PRInt32
* x
, PRInt32
* y
)
394 NS_ENSURE_STATE(mXULWindow
);
395 return mXULWindow
->GetPosition(x
, y
);
398 NS_IMETHODIMP
nsChromeTreeOwner::SetSize(PRInt32 cx
, PRInt32 cy
, PRBool fRepaint
)
400 NS_ENSURE_STATE(mXULWindow
);
401 return mXULWindow
->SetSize(cx
, cy
, fRepaint
);
404 NS_IMETHODIMP
nsChromeTreeOwner::GetSize(PRInt32
* cx
, PRInt32
* cy
)
406 NS_ENSURE_STATE(mXULWindow
);
407 return mXULWindow
->GetSize(cx
, cy
);
410 NS_IMETHODIMP
nsChromeTreeOwner::SetPositionAndSize(PRInt32 x
, PRInt32 y
, PRInt32 cx
,
411 PRInt32 cy
, PRBool fRepaint
)
413 NS_ENSURE_STATE(mXULWindow
);
414 return mXULWindow
->SetPositionAndSize(x
, y
, cx
, cy
, fRepaint
);
417 NS_IMETHODIMP
nsChromeTreeOwner::GetPositionAndSize(PRInt32
* x
, PRInt32
* y
, PRInt32
* cx
,
420 NS_ENSURE_STATE(mXULWindow
);
421 return mXULWindow
->GetPositionAndSize(x
, y
, cx
, cy
);
424 NS_IMETHODIMP
nsChromeTreeOwner::Repaint(PRBool aForce
)
426 NS_ENSURE_STATE(mXULWindow
);
427 return mXULWindow
->Repaint(aForce
);
430 NS_IMETHODIMP
nsChromeTreeOwner::GetParentWidget(nsIWidget
** aParentWidget
)
432 NS_ENSURE_STATE(mXULWindow
);
433 return mXULWindow
->GetParentWidget(aParentWidget
);
436 NS_IMETHODIMP
nsChromeTreeOwner::SetParentWidget(nsIWidget
* aParentWidget
)
438 NS_ASSERTION(PR_FALSE
, "You can't call this");
439 return NS_ERROR_NOT_IMPLEMENTED
;
442 NS_IMETHODIMP
nsChromeTreeOwner::GetParentNativeWindow(nativeWindow
* aParentNativeWindow
)
444 NS_ENSURE_STATE(mXULWindow
);
445 return mXULWindow
->GetParentNativeWindow(aParentNativeWindow
);
448 NS_IMETHODIMP
nsChromeTreeOwner::SetParentNativeWindow(nativeWindow aParentNativeWindow
)
450 NS_ASSERTION(PR_FALSE
, "You can't call this");
451 return NS_ERROR_NOT_IMPLEMENTED
;
454 NS_IMETHODIMP
nsChromeTreeOwner::GetVisibility(PRBool
* aVisibility
)
456 NS_ENSURE_STATE(mXULWindow
);
457 return mXULWindow
->GetVisibility(aVisibility
);
460 NS_IMETHODIMP
nsChromeTreeOwner::SetVisibility(PRBool aVisibility
)
462 NS_ENSURE_STATE(mXULWindow
);
463 return mXULWindow
->SetVisibility(aVisibility
);
466 NS_IMETHODIMP
nsChromeTreeOwner::GetEnabled(PRBool
*aEnabled
)
468 NS_ENSURE_STATE(mXULWindow
);
469 return mXULWindow
->GetEnabled(aEnabled
);
472 NS_IMETHODIMP
nsChromeTreeOwner::SetEnabled(PRBool aEnable
)
474 NS_ENSURE_STATE(mXULWindow
);
475 return mXULWindow
->SetEnabled(aEnable
);
478 NS_IMETHODIMP
nsChromeTreeOwner::GetBlurSuppression(PRBool
*aBlurSuppression
)
480 NS_ENSURE_STATE(mXULWindow
);
481 return mXULWindow
->GetBlurSuppression(aBlurSuppression
);
484 NS_IMETHODIMP
nsChromeTreeOwner::SetBlurSuppression(PRBool aBlurSuppression
)
486 NS_ENSURE_STATE(mXULWindow
);
487 return mXULWindow
->SetBlurSuppression(aBlurSuppression
);
490 NS_IMETHODIMP
nsChromeTreeOwner::GetMainWidget(nsIWidget
** aMainWidget
)
492 NS_ENSURE_ARG_POINTER(aMainWidget
);
493 NS_ENSURE_STATE(mXULWindow
);
495 *aMainWidget
= mXULWindow
->mWindow
;
496 NS_IF_ADDREF(*aMainWidget
);
501 NS_IMETHODIMP
nsChromeTreeOwner::SetFocus()
503 NS_ENSURE_STATE(mXULWindow
);
504 return mXULWindow
->SetFocus();
507 NS_IMETHODIMP
nsChromeTreeOwner::GetTitle(PRUnichar
** aTitle
)
509 NS_ENSURE_STATE(mXULWindow
);
510 return mXULWindow
->GetTitle(aTitle
);
513 NS_IMETHODIMP
nsChromeTreeOwner::SetTitle(const PRUnichar
* aTitle
)
515 NS_ENSURE_STATE(mXULWindow
);
516 return mXULWindow
->SetTitle(aTitle
);
519 //*****************************************************************************
520 // nsChromeTreeOwner::nsIWebProgressListener
521 //*****************************************************************************
524 nsChromeTreeOwner::OnProgressChange(nsIWebProgress
* aWebProgress
,
525 nsIRequest
* aRequest
,
526 PRInt32 aCurSelfProgress
,
527 PRInt32 aMaxSelfProgress
,
528 PRInt32 aCurTotalProgress
,
529 PRInt32 aMaxTotalProgress
)
535 nsChromeTreeOwner::OnStateChange(nsIWebProgress
* aWebProgress
,
536 nsIRequest
* aRequest
,
537 PRUint32 aProgressStateFlags
,
543 NS_IMETHODIMP
nsChromeTreeOwner::OnLocationChange(nsIWebProgress
* aWebProgress
,
544 nsIRequest
* aRequest
,
547 PRBool itsForYou
= PR_TRUE
;
550 NS_ENSURE_STATE(mXULWindow
);
551 nsCOMPtr
<nsIDOMWindow
> progressWin
;
552 aWebProgress
->GetDOMWindow(getter_AddRefs(progressWin
));
554 nsCOMPtr
<nsIDocShell
> docshell
;
555 mXULWindow
->GetDocShell(getter_AddRefs(docshell
));
556 nsCOMPtr
<nsIDOMWindow
> ourWin(do_QueryInterface(docshell
));
558 if (ourWin
!= progressWin
)
559 itsForYou
= PR_FALSE
;
562 // If loading a new root .xul document, then redo chrome.
564 NS_ENSURE_STATE(mXULWindow
);
565 mXULWindow
->mChromeLoaded
= PR_FALSE
;
571 nsChromeTreeOwner::OnStatusChange(nsIWebProgress
* aWebProgress
,
572 nsIRequest
* aRequest
,
574 const PRUnichar
* aMessage
)
582 nsChromeTreeOwner::OnSecurityChange(nsIWebProgress
*aWebProgress
,
583 nsIRequest
*aRequest
,
589 //*****************************************************************************
590 // nsChromeTreeOwner: Helpers
591 //*****************************************************************************
593 //*****************************************************************************
594 // nsChromeTreeOwner: Accessors
595 //*****************************************************************************
597 void nsChromeTreeOwner::XULWindow(nsXULWindow
* aXULWindow
)
599 mXULWindow
= aXULWindow
;
602 nsXULWindow
* nsChromeTreeOwner::XULWindow()