NS_IMETHODIMP nsMsgWindow::SetDomWindow(nsIDOMWindow * aWindow) { NS_ENSURE_ARG_POINTER(aWindow); mDomWindow = do_GetWeakReference(aWindow); nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(aWindow)); nsIDocShell *docShell = nsnull; if (win) docShell = win->GetDocShell(); nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(docShell)); if(docShellAsItem) { nsCOMPtr<nsIDocShellTreeItem> rootAsItem; docShellAsItem->GetSameTypeRootTreeItem(getter_AddRefs(rootAsItem)); nsCOMPtr<nsIDocShell> rootAsShell(do_QueryInterface(rootAsItem)); SetRootDocShell(rootAsShell); // force ourselves to figure out the message pane nsCOMPtr<nsIDocShell> messageWindowDocShell; GetMessageWindowDocShell(getter_AddRefs(messageWindowDocShell)); } return NS_OK; }
// XXXdholbert -- this function is duplicated in nsPrintDialogGTK.cpp // and needs to be unified in some generic utility class. nsIWidget *nsBaseFilePicker::DOMWindowToWidget(nsIDOMWindow *dw) { nsCOMPtr<nsIWidget> widget; nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(dw); if (window) { nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(window->GetDocShell())); while (!widget && baseWin) { baseWin->GetParentWidget(getter_AddRefs(widget)); if (!widget) { nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(baseWin)); if (!docShellAsItem) return nsnull; nsCOMPtr<nsIDocShellTreeItem> parent; docShellAsItem->GetSameTypeParent(getter_AddRefs(parent)); window = do_GetInterface(parent); if (!window) return nsnull; baseWin = do_QueryInterface(window->GetDocShell()); } } } // This will return a pointer that we're about to release, but // that's ok since the docshell (nsIBaseWindow) holds the widget // alive. return widget.get(); }
static void DOMWindowToTreeOwner( nsIDOMWindow *DOMWindow, nsIDocShellTreeOwner** aTreeOwner) { if (!DOMWindow) { return; // with webWindow unchanged -- its constructor gives it a null ptr } nsCOMPtr<nsIScriptGlobalObject> globalScript(do_QueryInterface(DOMWindow)); nsIDocShell *docShell = nsnull; if (globalScript) { docShell = globalScript->GetDocShell(); } nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(docShell)); if(!docShellAsItem) return; docShellAsItem->GetTreeOwner(aTreeOwner); }
NS_IMETHODIMP nsSubDocumentFrame::AttributeChanged(PRInt32 aNameSpaceID, nsIAtom* aAttribute, PRInt32 aModType) { if (aNameSpaceID != kNameSpaceID_None) { return NS_OK; } // If the noResize attribute changes, dis/allow frame to be resized if (aAttribute == nsGkAtoms::noresize) { // Note that we're not doing content type checks, but that's ok -- if // they'd fail we will just end up with a null framesetFrame. if (mContent->GetParent()->Tag() == nsGkAtoms::frameset) { nsIFrame* parentFrame = GetParent(); if (parentFrame) { // There is no interface for nsHTMLFramesetFrame so QI'ing to // concrete class, yay! nsHTMLFramesetFrame* framesetFrame = do_QueryFrame(parentFrame); if (framesetFrame) { framesetFrame->RecalculateBorderResize(); } } } } else if (aAttribute == nsGkAtoms::type) { if (!mFrameLoader) return NS_OK; if (!mContent->IsNodeOfType(nsINode::eXUL)) { return NS_OK; } // Note: This logic duplicates a lot of logic in // nsFrameLoader::EnsureDocShell. We should fix that. // Notify our enclosing chrome that our type has changed. We only do this // if our parent is chrome, since in all other cases we're random content // subframes and the treeowner shouldn't worry about us. nsCOMPtr<nsIDocShell> docShell; mFrameLoader->GetDocShell(getter_AddRefs(docShell)); nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(docShell)); if (!docShellAsItem) { return NS_OK; } nsCOMPtr<nsIDocShellTreeItem> parentItem; docShellAsItem->GetParent(getter_AddRefs(parentItem)); if (!parentItem) { return NS_OK; } PRInt32 parentType; parentItem->GetItemType(&parentType); if (parentType != nsIDocShellTreeItem::typeChrome) { return NS_OK; } nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner; parentItem->GetTreeOwner(getter_AddRefs(parentTreeOwner)); if (parentTreeOwner) { nsAutoString value; mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, value); PRBool is_primary = value.LowerCaseEqualsLiteral("content-primary"); #ifdef MOZ_XUL // when a content panel is no longer primary, hide any open popups it may have if (!is_primary) { nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); if (pm) pm->HidePopupsInDocShell(docShellAsItem); } #endif parentTreeOwner->ContentShellRemoved(docShellAsItem); if (value.LowerCaseEqualsLiteral("content") || StringBeginsWith(value, NS_LITERAL_STRING("content-"), nsCaseInsensitiveStringComparator())) { PRBool is_targetable = is_primary || value.LowerCaseEqualsLiteral("content-targetable"); parentTreeOwner->ContentShellAdded(docShellAsItem, is_primary, is_targetable, value); } } } return NS_OK; }
nsresult nsFrameLoader::EnsureDocShell() { if (mDocShell) { return NS_OK; } NS_ENSURE_STATE(!mDestroyCalled); // Get our parent docshell off the document of mOwnerContent // XXXbz this is such a total hack.... We really need to have a // better setup for doing this. nsIDocument* doc = mOwnerContent->GetDocument(); if (!doc) { return NS_ERROR_UNEXPECTED; } nsCOMPtr<nsIWebNavigation> parentAsWebNav = do_GetInterface(doc->GetScriptGlobalObject()); // Create the docshell... mDocShell = do_CreateInstance("@mozilla.org/webshell;1"); NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE); // Get the frame name and tell the docshell about it. nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell)); NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE); nsAutoString frameName; PRInt32 namespaceID = mOwnerContent->GetNameSpaceID(); if (namespaceID == kNameSpaceID_XHTML) { mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, frameName); } else { mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::name, frameName); // XXX if no NAME then use ID, after a transition period this will be // changed so that XUL only uses ID too (bug 254284). if (frameName.IsEmpty() && namespaceID == kNameSpaceID_XUL) { mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::id, frameName); } } if (!frameName.IsEmpty()) { docShellAsItem->SetName(frameName.get()); } // If our container is a web-shell, inform it that it has a new // child. If it's not a web-shell then some things will not operate // properly. nsCOMPtr<nsIDocShellTreeNode> parentAsNode(do_QueryInterface(parentAsWebNav)); if (parentAsNode) { // Note: This logic duplicates a lot of logic in // nsSubDocumentFrame::AttributeChanged. We should fix that. nsCOMPtr<nsIDocShellTreeItem> parentAsItem = do_QueryInterface(parentAsNode); PRInt32 parentType; parentAsItem->GetItemType(&parentType); nsAutoString value; PRBool isContent = PR_FALSE; if (mOwnerContent->IsNodeOfType(nsINode::eXUL)) { mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, value); } // we accept "content" and "content-xxx" values. // at time of writing, we expect "xxx" to be "primary" or "targetable", but // someday it might be an integer expressing priority or something else. isContent = value.LowerCaseEqualsLiteral("content") || StringBeginsWith(value, NS_LITERAL_STRING("content-"), nsCaseInsensitiveStringComparator()); if (isContent) { // The web shell's type is content. docShellAsItem->SetItemType(nsIDocShellTreeItem::typeContent); } else { // Inherit our type from our parent webshell. If it is // chrome, we'll be chrome. If it is content, we'll be // content. docShellAsItem->SetItemType(parentType); } parentAsNode->AddChild(docShellAsItem); if (parentType == nsIDocShellTreeItem::typeChrome && isContent) { mIsTopLevelContent = PR_TRUE; // XXXbz why is this in content code, exactly? We should handle // this some other way..... Not sure how yet. nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner; parentAsItem->GetTreeOwner(getter_AddRefs(parentTreeOwner)); PRBool is_primary = value.LowerCaseEqualsLiteral("content-primary"); if (parentTreeOwner) { PRBool is_targetable = is_primary || value.LowerCaseEqualsLiteral("content-targetable"); parentTreeOwner->ContentShellAdded(docShellAsItem, is_primary, is_targetable, value); } } // Make sure all shells have links back to the content element // in the nearest enclosing chrome shell. nsCOMPtr<nsIDOMEventTarget> chromeEventHandler; if (parentType == nsIDocShellTreeItem::typeChrome) { // Our parent shell is a chrome shell. It is therefore our nearest // enclosing chrome shell. chromeEventHandler = do_QueryInterface(mOwnerContent); NS_ASSERTION(chromeEventHandler, "This mContent should implement this."); } else { nsCOMPtr<nsIDocShell> parentShell(do_QueryInterface(parentAsNode)); // Our parent shell is a content shell. Get the chrome event // handler from it and use that for our shell as well. parentShell->GetChromeEventHandler(getter_AddRefs(chromeEventHandler)); } mDocShell->SetChromeEventHandler(chromeEventHandler); } // This is nasty, this code (the do_GetInterface(mDocShell) below) // *must* come *after* the above call to // mDocShell->SetChromeEventHandler() for the global window to get // the right chrome event handler. // Tell the window about the frame that hosts it. nsCOMPtr<nsIDOMElement> frame_element(do_QueryInterface(mOwnerContent)); NS_ASSERTION(frame_element, "frame loader owner element not a DOM element!"); nsCOMPtr<nsPIDOMWindow> win_private(do_GetInterface(mDocShell)); NS_ENSURE_TRUE(win_private, NS_ERROR_UNEXPECTED); nsIDOMElement* oldFrame = win_private->GetFrameElementInternal(); win_private->SetFrameElementInternal(frame_element); NS_ADDREF(frame_element.get()); NS_IF_RELEASE(oldFrame); nsCOMPtr<nsIBaseWindow> base_win(do_QueryInterface(mDocShell)); NS_ENSURE_TRUE(base_win, NS_ERROR_UNEXPECTED); // This is kinda whacky, this call doesn't really create anything, // but it must be called to make sure things are properly // initialized base_win->Create(); return NS_OK; }
nsresult nsWebShellWindow::Initialize(nsIXULWindow* aParent, nsIAppShell* aShell, nsIURI* aUrl, PRInt32 aInitialWidth, PRInt32 aInitialHeight, PRBool aIsHiddenWindow, nsWidgetInitData& widgetInitData) { nsresult rv; nsCOMPtr<nsIWidget> parentWidget; mIsHiddenWindow = aIsHiddenWindow; // XXX: need to get the default window size from prefs... // Doesn't come from prefs... will come from CSS/XUL/RDF nsRect r(0, 0, aInitialWidth, aInitialHeight); // Create top level window mWindow = do_CreateInstance(kWindowCID, &rv); if (NS_OK != rv) { return rv; } /* This next bit is troublesome. We carry two different versions of a pointer to our parent window. One is the parent window's widget, which is passed to our own widget. The other is a weak reference we keep here to our parent WebShellWindow. The former is useful to the widget, and we can't trust its treatment of the parent reference because they're platform- specific. The latter is useful to this class. A better implementation would be one in which the parent keeps strong references to its children and closes them before it allows itself to be closed. This would mimic the behaviour of OSes that support top-level child windows in OSes that do not. Later. */ nsCOMPtr<nsIBaseWindow> parentAsWin(do_QueryInterface(aParent)); if (parentAsWin) { parentAsWin->GetMainWidget(getter_AddRefs(parentWidget)); mParentWindow = do_GetWeakReference(aParent); } mWindow->SetClientData(this); mWindow->Create((nsIWidget *)parentWidget, // Parent nsIWidget r, // Widget dimensions nsWebShellWindow::HandleEvent, // Event handler function nsnull, // Device context aShell, // Application shell nsnull, // nsIToolkit &widgetInitData); // Widget initialization data mWindow->GetClientBounds(r); mWindow->SetBackgroundColor(NS_RGB(192,192,192)); // Create web shell mDocShell = do_CreateInstance("@mozilla.org/webshell;1"); NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE); // Make sure to set the item type on the docshell _before_ calling // Create() so it knows what type it is. nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell)); NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE); NS_ENSURE_SUCCESS(EnsureChromeTreeOwner(), NS_ERROR_FAILURE); docShellAsItem->SetTreeOwner(mChromeTreeOwner); docShellAsItem->SetItemType(nsIDocShellTreeItem::typeChrome); r.x = r.y = 0; nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(mDocShell)); NS_ENSURE_SUCCESS(docShellAsWin->InitWindow(nsnull, mWindow, r.x, r.y, r.width, r.height), NS_ERROR_FAILURE); NS_ENSURE_SUCCESS(docShellAsWin->Create(), NS_ERROR_FAILURE); // Attach a WebProgress listener.during initialization... nsCOMPtr<nsIWebProgress> webProgress(do_GetInterface(mDocShell, &rv)); if (webProgress) { webProgress->AddProgressListener(this, nsIWebProgress::NOTIFY_STATE_NETWORK); } if (nsnull != aUrl) { nsCAutoString tmpStr; rv = aUrl->GetSpec(tmpStr); if (NS_FAILED(rv)) return rv; NS_ConvertUTF8toUCS2 urlString(tmpStr); nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(mDocShell)); NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE); rv = webNav->LoadURI(urlString.get(), nsIWebNavigation::LOAD_FLAGS_NONE, nsnull, nsnull, nsnull); NS_ENSURE_SUCCESS(rv, rv); } return rv; }