Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 // Local Includes
8 #include "nsChromeTreeOwner.h"
9 #include "nsXULWindow.h"
11 // Helper Classes
12 #include "nsString.h"
13 #include "nsIEmbeddingSiteWindow.h"
14 #include "nsIServiceManager.h"
15 #include "nsIDocShellTreeItem.h"
17 // Interfaces needed to include
18 #include "nsIPrompt.h"
19 #include "nsIAuthPrompt.h"
20 #include "nsIBrowserDOMWindow.h"
21 #include "nsIWebProgress.h"
22 #include "nsIWidget.h"
23 #include "nsIWindowMediator.h"
24 #include "nsIDOMChromeWindow.h"
25 #include "nsIDOMNode.h"
26 #include "nsIDOMElement.h"
27 #include "nsIDOMNodeList.h"
28 #include "nsIDOMXULElement.h"
29 #include "nsIXULBrowserWindow.h"
30 #include "mozilla/dom/Element.h"
32 using namespace mozilla;
34 //*****************************************************************************
35 // nsChromeTreeOwner string literals
36 //*****************************************************************************
38 struct nsChromeTreeOwnerLiterals
39 {
40 const nsLiteralString kPersist;
41 const nsLiteralString kScreenX;
42 const nsLiteralString kScreenY;
43 const nsLiteralString kWidth;
44 const nsLiteralString kHeight;
45 const nsLiteralString kSizemode;
46 const nsLiteralString kSpace;
48 nsChromeTreeOwnerLiterals()
49 : NS_LITERAL_STRING_INIT(kPersist,"persist")
50 , NS_LITERAL_STRING_INIT(kScreenX,"screenX")
51 , NS_LITERAL_STRING_INIT(kScreenY,"screenY")
52 , NS_LITERAL_STRING_INIT(kWidth,"width")
53 , NS_LITERAL_STRING_INIT(kHeight,"height")
54 , NS_LITERAL_STRING_INIT(kSizemode,"sizemode")
55 , NS_LITERAL_STRING_INIT(kSpace," ")
56 {}
57 };
59 static nsChromeTreeOwnerLiterals *gLiterals;
61 nsresult
62 nsChromeTreeOwner::InitGlobals()
63 {
64 NS_ASSERTION(gLiterals == nullptr, "already initialized");
65 gLiterals = new nsChromeTreeOwnerLiterals();
66 if (!gLiterals)
67 return NS_ERROR_OUT_OF_MEMORY;
68 return NS_OK;
69 }
71 void
72 nsChromeTreeOwner::FreeGlobals()
73 {
74 delete gLiterals;
75 gLiterals = nullptr;
76 }
78 //*****************************************************************************
79 //*** nsChromeTreeOwner: Object Management
80 //*****************************************************************************
82 nsChromeTreeOwner::nsChromeTreeOwner() : mXULWindow(nullptr)
83 {
84 }
86 nsChromeTreeOwner::~nsChromeTreeOwner()
87 {
88 }
90 //*****************************************************************************
91 // nsChromeTreeOwner::nsISupports
92 //*****************************************************************************
94 NS_IMPL_ADDREF(nsChromeTreeOwner)
95 NS_IMPL_RELEASE(nsChromeTreeOwner)
97 NS_INTERFACE_MAP_BEGIN(nsChromeTreeOwner)
98 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocShellTreeOwner)
99 NS_INTERFACE_MAP_ENTRY(nsIDocShellTreeOwner)
100 NS_INTERFACE_MAP_ENTRY(nsIBaseWindow)
101 NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
102 NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
103 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
104 NS_INTERFACE_MAP_END
106 //*****************************************************************************
107 // nsChromeTreeOwner::nsIInterfaceRequestor
108 //*****************************************************************************
110 NS_IMETHODIMP nsChromeTreeOwner::GetInterface(const nsIID& aIID, void** aSink)
111 {
112 NS_ENSURE_ARG_POINTER(aSink);
114 if(aIID.Equals(NS_GET_IID(nsIPrompt))) {
115 NS_ENSURE_STATE(mXULWindow);
116 return mXULWindow->GetInterface(aIID, aSink);
117 }
118 if(aIID.Equals(NS_GET_IID(nsIAuthPrompt))) {
119 NS_ENSURE_STATE(mXULWindow);
120 return mXULWindow->GetInterface(aIID, aSink);
121 }
122 if(aIID.Equals(NS_GET_IID(nsIWebBrowserChrome))) {
123 NS_ENSURE_STATE(mXULWindow);
124 return mXULWindow->GetInterface(aIID, aSink);
125 }
126 if (aIID.Equals(NS_GET_IID(nsIEmbeddingSiteWindow))) {
127 NS_ENSURE_STATE(mXULWindow);
128 return mXULWindow->GetInterface(aIID, aSink);
129 }
130 if (aIID.Equals(NS_GET_IID(nsIXULWindow))) {
131 NS_ENSURE_STATE(mXULWindow);
132 return mXULWindow->QueryInterface(aIID, aSink);
133 }
135 return QueryInterface(aIID, aSink);
136 }
138 //*****************************************************************************
139 // nsChromeTreeOwner::nsIDocShellTreeOwner
140 //*****************************************************************************
142 NS_IMETHODIMP nsChromeTreeOwner::FindItemWithName(const char16_t* aName,
143 nsIDocShellTreeItem* aRequestor, nsIDocShellTreeItem* aOriginalRequestor,
144 nsIDocShellTreeItem** aFoundItem)
145 {
146 NS_DEFINE_CID(kWindowMediatorCID, NS_WINDOWMEDIATOR_CID);
148 NS_ENSURE_ARG_POINTER(aFoundItem);
150 *aFoundItem = nullptr;
152 bool fIs_Content = false;
154 /* Special Cases */
155 if(!aName || !*aName)
156 return NS_OK;
158 nsDependentString name(aName);
160 if(name.LowerCaseEqualsLiteral("_blank"))
161 return NS_OK;
162 // _main is an IE target which should be case-insensitive but isn't
163 // see bug 217886 for details
164 if(name.LowerCaseEqualsLiteral("_content") || name.EqualsLiteral("_main"))
165 {
166 NS_ENSURE_STATE(mXULWindow);
167 fIs_Content = true;
168 mXULWindow->GetPrimaryContentShell(aFoundItem);
169 if(*aFoundItem)
170 return NS_OK;
171 // Otherwise fall through and ask the other windows for a content area.
172 }
174 nsCOMPtr<nsIWindowMediator> windowMediator(do_GetService(kWindowMediatorCID));
175 NS_ENSURE_TRUE(windowMediator, NS_ERROR_FAILURE);
177 nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
178 NS_ENSURE_SUCCESS(windowMediator->GetXULWindowEnumerator(nullptr,
179 getter_AddRefs(windowEnumerator)), NS_ERROR_FAILURE);
181 bool more;
183 windowEnumerator->HasMoreElements(&more);
184 while(more)
185 {
186 nsCOMPtr<nsISupports> nextWindow = nullptr;
187 windowEnumerator->GetNext(getter_AddRefs(nextWindow));
188 nsCOMPtr<nsIXULWindow> xulWindow(do_QueryInterface(nextWindow));
189 NS_ENSURE_TRUE(xulWindow, NS_ERROR_FAILURE);
191 nsCOMPtr<nsIDocShellTreeItem> shellAsTreeItem;
193 if(fIs_Content)
194 {
195 xulWindow->GetPrimaryContentShell(aFoundItem);
196 }
197 else
198 {
199 // Note that we don't look for targetable content shells here...
200 // in fact, we aren't looking for content shells at all!
201 nsCOMPtr<nsIDocShell> shell;
202 xulWindow->GetDocShell(getter_AddRefs(shell));
203 shellAsTreeItem = do_QueryInterface(shell);
204 if (shellAsTreeItem) {
205 // Get the root tree item of same type, since roots are the only
206 // things that call into the treeowner to look for named items.
207 nsCOMPtr<nsIDocShellTreeItem> root;
208 shellAsTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(root));
209 shellAsTreeItem = root;
210 }
211 if(shellAsTreeItem && aRequestor != shellAsTreeItem)
212 {
213 // Do this so we can pass in the tree owner as the requestor so the child knows not
214 // to call back up.
215 nsCOMPtr<nsIDocShellTreeOwner> shellOwner;
216 shellAsTreeItem->GetTreeOwner(getter_AddRefs(shellOwner));
217 nsCOMPtr<nsISupports> shellOwnerSupports(do_QueryInterface(shellOwner));
219 shellAsTreeItem->FindItemWithName(aName, shellOwnerSupports,
220 aOriginalRequestor, aFoundItem);
221 }
222 }
223 if(*aFoundItem)
224 return NS_OK;
225 windowEnumerator->HasMoreElements(&more);
226 }
227 return NS_OK;
228 }
230 NS_IMETHODIMP
231 nsChromeTreeOwner::ContentShellAdded(nsIDocShellTreeItem* aContentShell,
232 bool aPrimary, bool aTargetable,
233 const nsAString& aID)
234 {
235 NS_ENSURE_STATE(mXULWindow);
236 return mXULWindow->ContentShellAdded(aContentShell, aPrimary, aTargetable,
237 aID);
238 }
240 NS_IMETHODIMP
241 nsChromeTreeOwner::ContentShellRemoved(nsIDocShellTreeItem* aContentShell)
242 {
243 NS_ENSURE_STATE(mXULWindow);
244 return mXULWindow->ContentShellRemoved(aContentShell);
245 }
247 NS_IMETHODIMP nsChromeTreeOwner::GetPrimaryContentShell(nsIDocShellTreeItem** aShell)
248 {
249 NS_ENSURE_STATE(mXULWindow);
250 return mXULWindow->GetPrimaryContentShell(aShell);
251 }
253 NS_IMETHODIMP
254 nsChromeTreeOwner::GetContentWindow(JSContext* aCx, JS::MutableHandle<JS::Value> aVal)
255 {
256 NS_ENSURE_STATE(mXULWindow);
258 nsCOMPtr<nsIDOMWindow> domWin;
259 mXULWindow->GetWindowDOMWindow(getter_AddRefs(domWin));
260 nsCOMPtr<nsIDOMChromeWindow> chromeWin = do_QueryInterface(domWin);
261 if (!chromeWin)
262 return NS_OK;
264 nsCOMPtr<nsIBrowserDOMWindow> browserDOMWin;
265 chromeWin->GetBrowserDOMWindow(getter_AddRefs(browserDOMWin));
266 if (!browserDOMWin)
267 return NS_OK;
269 return browserDOMWin->GetContentWindow(aVal);
270 }
272 NS_IMETHODIMP nsChromeTreeOwner::SizeShellTo(nsIDocShellTreeItem* aShellItem,
273 int32_t aCX, int32_t aCY)
274 {
275 NS_ENSURE_STATE(mXULWindow);
276 return mXULWindow->SizeShellTo(aShellItem, aCX, aCY);
277 }
279 NS_IMETHODIMP
280 nsChromeTreeOwner::SetPersistence(bool aPersistPosition,
281 bool aPersistSize,
282 bool aPersistSizeMode)
283 {
284 NS_ENSURE_STATE(mXULWindow);
285 nsCOMPtr<dom::Element> docShellElement = mXULWindow->GetWindowDOMElement();
286 if (!docShellElement)
287 return NS_ERROR_FAILURE;
289 nsAutoString persistString;
290 docShellElement->GetAttribute(gLiterals->kPersist, persistString);
292 bool saveString = false;
293 int32_t index;
295 #define FIND_PERSIST_STRING(aString, aCond) \
296 index = persistString.Find(aString); \
297 if (!aCond && index > kNotFound) { \
298 persistString.Cut(index, aString.Length()); \
299 saveString = true; \
300 } else if (aCond && index == kNotFound) { \
301 persistString.Append(gLiterals->kSpace + aString); \
302 saveString = true; \
303 }
304 FIND_PERSIST_STRING(gLiterals->kScreenX, aPersistPosition);
305 FIND_PERSIST_STRING(gLiterals->kScreenY, aPersistPosition);
306 FIND_PERSIST_STRING(gLiterals->kWidth, aPersistSize);
307 FIND_PERSIST_STRING(gLiterals->kHeight, aPersistSize);
308 FIND_PERSIST_STRING(gLiterals->kSizemode, aPersistSizeMode);
310 ErrorResult rv;
311 if (saveString) {
312 docShellElement->SetAttribute(gLiterals->kPersist, persistString, rv);
313 }
315 return NS_OK;
316 }
318 NS_IMETHODIMP
319 nsChromeTreeOwner::GetPersistence(bool* aPersistPosition,
320 bool* aPersistSize,
321 bool* aPersistSizeMode)
322 {
323 NS_ENSURE_STATE(mXULWindow);
324 nsCOMPtr<dom::Element> docShellElement = mXULWindow->GetWindowDOMElement();
325 if (!docShellElement)
326 return NS_ERROR_FAILURE;
328 nsAutoString persistString;
329 docShellElement->GetAttribute(gLiterals->kPersist, persistString);
331 // data structure doesn't quite match the question, but it's close enough
332 // for what we want (since this method is never actually called...)
333 if (aPersistPosition)
334 *aPersistPosition = persistString.Find(gLiterals->kScreenX) > kNotFound ||
335 persistString.Find(gLiterals->kScreenY) > kNotFound;
336 if (aPersistSize)
337 *aPersistSize = persistString.Find(gLiterals->kWidth) > kNotFound ||
338 persistString.Find(gLiterals->kHeight) > kNotFound;
339 if (aPersistSizeMode)
340 *aPersistSizeMode = persistString.Find(gLiterals->kSizemode) > kNotFound;
342 return NS_OK;
343 }
345 NS_IMETHODIMP
346 nsChromeTreeOwner::GetTargetableShellCount(uint32_t* aResult)
347 {
348 *aResult = 0;
349 return NS_OK;
350 }
352 //*****************************************************************************
353 // nsChromeTreeOwner::nsIBaseWindow
354 //*****************************************************************************
356 NS_IMETHODIMP nsChromeTreeOwner::InitWindow(nativeWindow aParentNativeWindow,
357 nsIWidget* parentWidget, int32_t x, int32_t y, int32_t cx, int32_t cy)
358 {
359 // Ignore widget parents for now. Don't think those are a vaild thing to call.
360 NS_ENSURE_SUCCESS(SetPositionAndSize(x, y, cx, cy, false), NS_ERROR_FAILURE);
362 return NS_OK;
363 }
365 NS_IMETHODIMP nsChromeTreeOwner::Create()
366 {
367 NS_ASSERTION(false, "You can't call this");
368 return NS_ERROR_UNEXPECTED;
369 }
371 NS_IMETHODIMP nsChromeTreeOwner::Destroy()
372 {
373 NS_ENSURE_STATE(mXULWindow);
374 return mXULWindow->Destroy();
375 }
377 NS_IMETHODIMP nsChromeTreeOwner::GetUnscaledDevicePixelsPerCSSPixel(double *aScale)
378 {
379 NS_ENSURE_STATE(mXULWindow);
380 return mXULWindow->GetUnscaledDevicePixelsPerCSSPixel(aScale);
381 }
383 NS_IMETHODIMP nsChromeTreeOwner::SetPosition(int32_t x, int32_t y)
384 {
385 NS_ENSURE_STATE(mXULWindow);
386 return mXULWindow->SetPosition(x, y);
387 }
389 NS_IMETHODIMP nsChromeTreeOwner::GetPosition(int32_t* x, int32_t* y)
390 {
391 NS_ENSURE_STATE(mXULWindow);
392 return mXULWindow->GetPosition(x, y);
393 }
395 NS_IMETHODIMP nsChromeTreeOwner::SetSize(int32_t cx, int32_t cy, bool fRepaint)
396 {
397 NS_ENSURE_STATE(mXULWindow);
398 return mXULWindow->SetSize(cx, cy, fRepaint);
399 }
401 NS_IMETHODIMP nsChromeTreeOwner::GetSize(int32_t* cx, int32_t* cy)
402 {
403 NS_ENSURE_STATE(mXULWindow);
404 return mXULWindow->GetSize(cx, cy);
405 }
407 NS_IMETHODIMP nsChromeTreeOwner::SetPositionAndSize(int32_t x, int32_t y, int32_t cx,
408 int32_t cy, bool fRepaint)
409 {
410 NS_ENSURE_STATE(mXULWindow);
411 return mXULWindow->SetPositionAndSize(x, y, cx, cy, fRepaint);
412 }
414 NS_IMETHODIMP nsChromeTreeOwner::GetPositionAndSize(int32_t* x, int32_t* y, int32_t* cx,
415 int32_t* cy)
416 {
417 NS_ENSURE_STATE(mXULWindow);
418 return mXULWindow->GetPositionAndSize(x, y, cx, cy);
419 }
421 NS_IMETHODIMP nsChromeTreeOwner::Repaint(bool aForce)
422 {
423 NS_ENSURE_STATE(mXULWindow);
424 return mXULWindow->Repaint(aForce);
425 }
427 NS_IMETHODIMP nsChromeTreeOwner::GetParentWidget(nsIWidget** aParentWidget)
428 {
429 NS_ENSURE_STATE(mXULWindow);
430 return mXULWindow->GetParentWidget(aParentWidget);
431 }
433 NS_IMETHODIMP nsChromeTreeOwner::SetParentWidget(nsIWidget* aParentWidget)
434 {
435 NS_ASSERTION(false, "You can't call this");
436 return NS_ERROR_NOT_IMPLEMENTED;
437 }
439 NS_IMETHODIMP nsChromeTreeOwner::GetParentNativeWindow(nativeWindow* aParentNativeWindow)
440 {
441 NS_ENSURE_STATE(mXULWindow);
442 return mXULWindow->GetParentNativeWindow(aParentNativeWindow);
443 }
445 NS_IMETHODIMP nsChromeTreeOwner::SetParentNativeWindow(nativeWindow aParentNativeWindow)
446 {
447 NS_ASSERTION(false, "You can't call this");
448 return NS_ERROR_NOT_IMPLEMENTED;
449 }
451 NS_IMETHODIMP nsChromeTreeOwner::GetNativeHandle(nsAString& aNativeHandle)
452 {
453 NS_ENSURE_STATE(mXULWindow);
454 return mXULWindow->GetNativeHandle(aNativeHandle);
455 }
457 NS_IMETHODIMP nsChromeTreeOwner::GetVisibility(bool* aVisibility)
458 {
459 NS_ENSURE_STATE(mXULWindow);
460 return mXULWindow->GetVisibility(aVisibility);
461 }
463 NS_IMETHODIMP nsChromeTreeOwner::SetVisibility(bool aVisibility)
464 {
465 NS_ENSURE_STATE(mXULWindow);
466 return mXULWindow->SetVisibility(aVisibility);
467 }
469 NS_IMETHODIMP nsChromeTreeOwner::GetEnabled(bool *aEnabled)
470 {
471 NS_ENSURE_STATE(mXULWindow);
472 return mXULWindow->GetEnabled(aEnabled);
473 }
475 NS_IMETHODIMP nsChromeTreeOwner::SetEnabled(bool aEnable)
476 {
477 NS_ENSURE_STATE(mXULWindow);
478 return mXULWindow->SetEnabled(aEnable);
479 }
481 NS_IMETHODIMP nsChromeTreeOwner::GetMainWidget(nsIWidget** aMainWidget)
482 {
483 NS_ENSURE_ARG_POINTER(aMainWidget);
484 NS_ENSURE_STATE(mXULWindow);
486 *aMainWidget = mXULWindow->mWindow;
487 NS_IF_ADDREF(*aMainWidget);
489 return NS_OK;
490 }
492 NS_IMETHODIMP nsChromeTreeOwner::SetFocus()
493 {
494 NS_ENSURE_STATE(mXULWindow);
495 return mXULWindow->SetFocus();
496 }
498 NS_IMETHODIMP nsChromeTreeOwner::GetTitle(char16_t** aTitle)
499 {
500 NS_ENSURE_STATE(mXULWindow);
501 return mXULWindow->GetTitle(aTitle);
502 }
504 NS_IMETHODIMP nsChromeTreeOwner::SetTitle(const char16_t* aTitle)
505 {
506 NS_ENSURE_STATE(mXULWindow);
507 return mXULWindow->SetTitle(aTitle);
508 }
510 //*****************************************************************************
511 // nsChromeTreeOwner::nsIWebProgressListener
512 //*****************************************************************************
514 NS_IMETHODIMP
515 nsChromeTreeOwner::OnProgressChange(nsIWebProgress* aWebProgress,
516 nsIRequest* aRequest,
517 int32_t aCurSelfProgress,
518 int32_t aMaxSelfProgress,
519 int32_t aCurTotalProgress,
520 int32_t aMaxTotalProgress)
521 {
522 return NS_OK;
523 }
525 NS_IMETHODIMP
526 nsChromeTreeOwner::OnStateChange(nsIWebProgress* aWebProgress,
527 nsIRequest* aRequest,
528 uint32_t aProgressStateFlags,
529 nsresult aStatus)
530 {
531 return NS_OK;
532 }
534 NS_IMETHODIMP nsChromeTreeOwner::OnLocationChange(nsIWebProgress* aWebProgress,
535 nsIRequest* aRequest,
536 nsIURI* aLocation,
537 uint32_t aFlags)
538 {
539 bool itsForYou = true;
541 if (aWebProgress) {
542 NS_ENSURE_STATE(mXULWindow);
543 nsCOMPtr<nsIDOMWindow> progressWin;
544 aWebProgress->GetDOMWindow(getter_AddRefs(progressWin));
546 nsCOMPtr<nsIDocShell> docshell;
547 mXULWindow->GetDocShell(getter_AddRefs(docshell));
548 nsCOMPtr<nsIDOMWindow> ourWin(do_QueryInterface(docshell));
550 if (ourWin != progressWin)
551 itsForYou = false;
552 }
554 // If loading a new root .xul document, then redo chrome.
555 if (itsForYou) {
556 NS_ENSURE_STATE(mXULWindow);
557 mXULWindow->mChromeLoaded = false;
558 }
559 return NS_OK;
560 }
562 NS_IMETHODIMP
563 nsChromeTreeOwner::OnStatusChange(nsIWebProgress* aWebProgress,
564 nsIRequest* aRequest,
565 nsresult aStatus,
566 const char16_t* aMessage)
567 {
568 return NS_OK;
569 }
573 NS_IMETHODIMP
574 nsChromeTreeOwner::OnSecurityChange(nsIWebProgress *aWebProgress,
575 nsIRequest *aRequest,
576 uint32_t state)
577 {
578 return NS_OK;
579 }
581 //*****************************************************************************
582 // nsChromeTreeOwner: Helpers
583 //*****************************************************************************
585 //*****************************************************************************
586 // nsChromeTreeOwner: Accessors
587 //*****************************************************************************
589 void nsChromeTreeOwner::XULWindow(nsXULWindow* aXULWindow)
590 {
591 mXULWindow = aXULWindow;
592 }
594 nsXULWindow* nsChromeTreeOwner::XULWindow()
595 {
596 return mXULWindow;
597 }