mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 433616 part 1. Make it possible to create a document viewer with no parent widget or container, and make various code saner about handling null document/prescontext/documentviewer containers. r=roc, sr=jst
This commit is contained in:
parent
fd441c1339
commit
d674c8ca02
@ -807,6 +807,13 @@ public:
|
||||
*/
|
||||
static PRBool IsChromeDoc(nsIDocument *aDocument);
|
||||
|
||||
/**
|
||||
* Returns true if aDocument belongs to a chrome docshell for
|
||||
* display purposes. Returns false for null documents or documents
|
||||
* which do not belong to a docshell.
|
||||
*/
|
||||
static PRBool IsInChromeDocshell(nsIDocument *aDocument);
|
||||
|
||||
/**
|
||||
* Release *aSupportsPtr when the shutdown notification is received
|
||||
*/
|
||||
|
@ -2903,6 +2903,24 @@ nsContentUtils::IsChromeDoc(nsIDocument *aDocument)
|
||||
return aDocument->NodePrincipal() == systemPrincipal;
|
||||
}
|
||||
|
||||
// static
|
||||
PRBool
|
||||
nsContentUtils::IsInChromeDocshell(nsIDocument *aDocument)
|
||||
{
|
||||
if (!aDocument) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> docContainer = aDocument->GetContainer();
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShell(do_QueryInterface(docContainer));
|
||||
PRInt32 itemType = nsIDocShellTreeItem::typeContent;
|
||||
if (docShell) {
|
||||
docShell->GetItemType(&itemType);
|
||||
}
|
||||
|
||||
return itemType == nsIDocShellTreeItem::typeChrome;
|
||||
}
|
||||
|
||||
// static
|
||||
nsIContentPolicy*
|
||||
nsContentUtils::GetContentPolicy()
|
||||
|
@ -5727,9 +5727,7 @@ nsDocument::FlushPendingNotifications(mozFlushType aType)
|
||||
|
||||
// Should we be flushing pending binding constructors in here?
|
||||
|
||||
nsPIDOMWindow *window = GetWindow();
|
||||
|
||||
if (aType <= Flush_ContentAndNotify || !window) {
|
||||
if (aType <= Flush_ContentAndNotify) {
|
||||
// Nothing to do here
|
||||
return;
|
||||
}
|
||||
|
@ -6282,6 +6282,9 @@ nsEventStateManager::ShiftFocusByDoc(PRBool aForward)
|
||||
|
||||
nsCOMPtr<nsISupports> pcContainer = mPresContext->GetContainer();
|
||||
nsCOMPtr<nsIDocShellTreeNode> curNode = do_QueryInterface(pcContainer);
|
||||
if (!curNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
// perform a depth first search (preorder) of the docshell tree
|
||||
// looking for an HTML Frame or a chrome document
|
||||
|
@ -709,10 +709,6 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aContainer));
|
||||
|
||||
nsCOMPtr<nsIDocumentCharsetInfo> dcInfo;
|
||||
docShell->GetDocumentCharsetInfo(getter_AddRefs(dcInfo));
|
||||
PRInt32 textType = GET_BIDI_OPTION_TEXTTYPE(GetBidiOptions());
|
||||
|
||||
// Look for the parent document. Note that at this point we don't have our
|
||||
@ -722,11 +718,17 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
|
||||
// in this block of code, if we get an error result, we return it
|
||||
// but if we get a null pointer, that's perfectly legal for parent
|
||||
// and parentContentViewer
|
||||
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aContainer));
|
||||
|
||||
// No support yet for docshell-less HTML
|
||||
NS_ENSURE_TRUE(docShell || IsXHTML(), NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(docShell));
|
||||
NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
|
||||
docShellAsItem->GetSameTypeParent(getter_AddRefs(parentAsItem));
|
||||
if (docShellAsItem) {
|
||||
docShellAsItem->GetSameTypeParent(getter_AddRefs(parentAsItem));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShell> parent(do_QueryInterface(parentAsItem));
|
||||
nsCOMPtr<nsIDocument> parentDocument;
|
||||
@ -747,7 +749,9 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
|
||||
nsCOMPtr<nsIMarkupDocumentViewer> muCV;
|
||||
PRBool muCVIsParent = PR_FALSE;
|
||||
nsCOMPtr<nsIContentViewer> cv;
|
||||
docShell->GetContentViewer(getter_AddRefs(cv));
|
||||
if (docShell) {
|
||||
docShell->GetContentViewer(getter_AddRefs(cv));
|
||||
}
|
||||
if (cv) {
|
||||
muCV = do_QueryInterface(cv);
|
||||
} else {
|
||||
@ -784,6 +788,11 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
|
||||
parserCharsetSource = charsetSource;
|
||||
parserCharset = charset;
|
||||
} else {
|
||||
NS_ASSERTION(docShell && docShellAsItem, "Unexpected null value");
|
||||
|
||||
nsCOMPtr<nsIDocumentCharsetInfo> dcInfo;
|
||||
docShell->GetDocumentCharsetInfo(getter_AddRefs(dcInfo));
|
||||
|
||||
charsetSource = kCharsetUninitialized;
|
||||
wyciwygChannel = do_QueryInterface(aChannel);
|
||||
|
||||
|
@ -423,7 +423,7 @@ nsFocusController::GetWindowFromDocument(nsIDOMDocument* aDocument)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDocument);
|
||||
if (!doc)
|
||||
return NS_OK;
|
||||
return nsnull;
|
||||
|
||||
return doc->GetWindow();
|
||||
}
|
||||
|
@ -433,7 +433,7 @@ protected:
|
||||
nsCOMPtr<nsIContentViewer> mPreviousViewer;
|
||||
nsCOMPtr<nsISHEntry> mSHEntry;
|
||||
|
||||
nsIWidget* mParentWidget; // purposely won't be ref counted
|
||||
nsIWidget* mParentWidget; // purposely won't be ref counted. May be null
|
||||
|
||||
// mTextZoom/mPageZoom record the textzoom/pagezoom of the first (galley)
|
||||
// presshell only.
|
||||
@ -958,14 +958,11 @@ DocumentViewerImpl::LoadComplete(nsresult aStatus)
|
||||
// First, get the window from the document...
|
||||
nsPIDOMWindow *window = mDocument->GetWindow();
|
||||
|
||||
// Fail if no window is available...
|
||||
NS_ENSURE_TRUE(window, NS_ERROR_NULL_POINTER);
|
||||
|
||||
mLoaded = PR_TRUE;
|
||||
|
||||
// Now, fire either an OnLoad or OnError event to the document...
|
||||
PRBool restoring = PR_FALSE;
|
||||
if(NS_SUCCEEDED(aStatus)) {
|
||||
if(NS_SUCCEEDED(aStatus) && window) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent event(PR_TRUE, NS_LOAD);
|
||||
event.flags |= NS_EVENT_FLAG_CANT_BUBBLE;
|
||||
@ -1241,12 +1238,6 @@ DocumentViewerImpl::Open(nsISupports *aState, nsISHEntry *aSHEntry)
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
// Our container might have gone away while we were closed.
|
||||
// If this is the case, we must fail to open so we don't crash.
|
||||
nsCOMPtr<nsISupports> container = do_QueryReferent(mContainer);
|
||||
if (!container)
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
nsRect bounds;
|
||||
mWindow->GetBounds(bounds);
|
||||
|
||||
@ -1262,11 +1253,13 @@ DocumentViewerImpl::Open(nsISupports *aState, nsISHEntry *aSHEntry)
|
||||
// Rehook the child presentations. The child shells are still in
|
||||
// session history, so get them from there.
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> item;
|
||||
PRInt32 itemIndex = 0;
|
||||
while (NS_SUCCEEDED(aSHEntry->ChildShellAt(itemIndex++,
|
||||
getter_AddRefs(item))) && item) {
|
||||
AttachContainerRecurse(nsCOMPtr<nsIDocShell>(do_QueryInterface(item)));
|
||||
if (aSHEntry) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> item;
|
||||
PRInt32 itemIndex = 0;
|
||||
while (NS_SUCCEEDED(aSHEntry->ChildShellAt(itemIndex++,
|
||||
getter_AddRefs(item))) && item) {
|
||||
AttachContainerRecurse(nsCOMPtr<nsIDocShell>(do_QueryInterface(item)));
|
||||
}
|
||||
}
|
||||
|
||||
SyncParentSubDocMap();
|
||||
@ -1873,11 +1866,11 @@ DocumentViewerImpl::Show(void)
|
||||
|
||||
if (mDocument && !mPresShell && !mWindow) {
|
||||
nsCOMPtr<nsIBaseWindow> base_win(do_QueryReferent(mContainer));
|
||||
NS_ENSURE_TRUE(base_win, NS_ERROR_UNEXPECTED);
|
||||
|
||||
base_win->GetParentWidget(&mParentWidget);
|
||||
NS_ENSURE_TRUE(mParentWidget, NS_ERROR_UNEXPECTED);
|
||||
mParentWidget->Release(); // GetParentWidget AddRefs, but mParentWidget is weak
|
||||
if (base_win) {
|
||||
base_win->GetParentWidget(&mParentWidget);
|
||||
NS_ENSURE_TRUE(mParentWidget, NS_ERROR_UNEXPECTED);
|
||||
mParentWidget->Release(); // GetParentWidget AddRefs, but mParentWidget is weak
|
||||
}
|
||||
|
||||
nsresult rv = CreateDeviceContext(mParentWidget);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -1894,7 +1887,12 @@ DocumentViewerImpl::Show(void)
|
||||
}
|
||||
|
||||
nsRect tbounds;
|
||||
mParentWidget->GetBounds(tbounds);
|
||||
if (mParentWidget) {
|
||||
mParentWidget->GetBounds(tbounds);
|
||||
} else {
|
||||
// No good default size; just size to 0 by 0 for lack of anything better.
|
||||
tbounds = nsRect(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
rv = MakeWindow(nsSize(mPresContext->DevPixelsToAppUnits(tbounds.width),
|
||||
mPresContext->DevPixelsToAppUnits(tbounds.height)));
|
||||
@ -2098,9 +2096,11 @@ DocumentViewerImpl::CreateStyleSet(nsIDocument* aDocument,
|
||||
// The document will fill in the document sheets when we create the presshell
|
||||
|
||||
// Handle the user sheets.
|
||||
PRInt32 shellType = nsIDocShellTreeItem::typeContent;;
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShell(do_QueryReferent(mContainer));
|
||||
PRInt32 shellType;
|
||||
docShell->GetItemType(&shellType);
|
||||
if (docShell) {
|
||||
docShell->GetItemType(&shellType);
|
||||
}
|
||||
nsICSSStyleSheet* sheet = nsnull;
|
||||
if (shellType == nsIDocShellTreeItem::typeChrome) {
|
||||
sheet = nsLayoutStylesheetCache::UserChromeSheet();
|
||||
@ -2119,7 +2119,9 @@ DocumentViewerImpl::CreateStyleSet(nsIDocument* aDocument,
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsCOMPtr<nsICSSStyleSheet> csssheet;
|
||||
|
||||
ds->GetChromeEventHandler(getter_AddRefs(chromeHandler));
|
||||
if (ds) {
|
||||
ds->GetChromeEventHandler(getter_AddRefs(chromeHandler));
|
||||
}
|
||||
if (chromeHandler) {
|
||||
nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(chromeHandler));
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(elt));
|
||||
@ -2209,7 +2211,8 @@ DocumentViewerImpl::MakeWindow(const nsSize& aSize)
|
||||
|
||||
// Create a child window of the parent that is our "root view/window"
|
||||
// if aParentWidget has a view, we'll hook our view manager up to its view tree
|
||||
nsIView* containerView = nsIView::GetViewFor(mParentWidget);
|
||||
nsIView* containerView =
|
||||
mParentWidget ? nsIView::GetViewFor(mParentWidget) : nsnull;
|
||||
|
||||
if (containerView) {
|
||||
// see if the containerView has already been hooked into a foreign view manager hierarchy
|
||||
@ -2251,8 +2254,21 @@ DocumentViewerImpl::MakeWindow(const nsSize& aSize)
|
||||
// pass in a native widget to be the parent widget ONLY if the view hierarchy will stand alone.
|
||||
// otherwise the view will find its own parent widget and "do the right thing" to
|
||||
// establish a parent/child widget relationship
|
||||
rv = view->CreateWidget(kWidgetCID, nsnull,
|
||||
containerView != nsnull ? nsnull : mParentWidget->GetNativeData(NS_NATIVE_WIDGET),
|
||||
nsWidgetInitData initData;
|
||||
nsWidgetInitData* initDataPtr;
|
||||
if (!mParentWidget) {
|
||||
initDataPtr = &initData;
|
||||
initData.mWindowType = eWindowType_invisible;
|
||||
|
||||
initData.mContentType =
|
||||
nsContentUtils::IsInChromeDocshell(mDocument) ?
|
||||
eContentTypeUI : eContentTypeContent;
|
||||
} else {
|
||||
initDataPtr = nsnull;
|
||||
}
|
||||
rv = view->CreateWidget(kWidgetCID, initDataPtr,
|
||||
(containerView != nsnull || !mParentWidget) ?
|
||||
nsnull : mParentWidget->GetNativeData(NS_NATIVE_WIDGET),
|
||||
PR_TRUE, PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
@ -2273,12 +2289,14 @@ DocumentViewerImpl::MakeWindow(const nsSize& aSize)
|
||||
nsresult
|
||||
DocumentViewerImpl::CreateDeviceContext(nsIWidget* aWidget)
|
||||
{
|
||||
NS_PRECONDITION(!mDeviceContext, "How come we're calling this?");
|
||||
if (aWidget) {
|
||||
mDeviceContext = do_CreateInstance(kDeviceContextCID);
|
||||
NS_ENSURE_TRUE(mDeviceContext, NS_ERROR_FAILURE);
|
||||
mDeviceContext->Init(aWidget->GetNativeData(NS_NATIVE_WIDGET));
|
||||
}
|
||||
NS_PRECONDITION(!mPresShell && !mPresContext && !mWindow,
|
||||
"This will screw up our existing presentation");
|
||||
// Create a device context even if we already have one, since our widget
|
||||
// might have changed.
|
||||
mDeviceContext = do_CreateInstance(kDeviceContextCID);
|
||||
NS_ENSURE_TRUE(mDeviceContext, NS_ERROR_FAILURE);
|
||||
mDeviceContext->Init(aWidget ?
|
||||
aWidget->GetNativeData(NS_NATIVE_WIDGET) : nsnull);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -2762,8 +2780,6 @@ DocumentViewerImpl::GetAuthorStyleDisabled(PRBool* aStyleDisabled)
|
||||
NS_IMETHODIMP
|
||||
DocumentViewerImpl::GetDefaultCharacterSet(nsACString& aDefaultCharacterSet)
|
||||
{
|
||||
NS_ENSURE_STATE(nsCOMPtr<nsISupports>(do_QueryReferent(mContainer)));
|
||||
|
||||
if (mDefaultCharacterSet.IsEmpty())
|
||||
{
|
||||
const nsAdoptingString& defCharset =
|
||||
@ -3058,9 +3074,10 @@ NS_IMETHODIMP DocumentViewerImpl::SizeToContent()
|
||||
{
|
||||
NS_ENSURE_TRUE(mDocument, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
// Skip doing this on docshell-less documents for now
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryReferent(mContainer));
|
||||
NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);
|
||||
|
||||
NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellParent;
|
||||
docShellAsItem->GetSameTypeParent(getter_AddRefs(docShellParent));
|
||||
|
||||
|
@ -1804,49 +1804,35 @@ PresShell::SetPreferenceStyleRules(PRBool aForceReflow)
|
||||
|
||||
NS_PRECONDITION(mPresContext, "presContext cannot be null");
|
||||
if (mPresContext) {
|
||||
nsresult result = NS_OK;
|
||||
|
||||
// first, make sure this is not a chrome shell
|
||||
nsCOMPtr<nsISupports> container = mPresContext->GetContainer();
|
||||
if (container) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShell(do_QueryInterface(container, &result));
|
||||
if (NS_SUCCEEDED(result) && docShell){
|
||||
PRInt32 docShellType;
|
||||
result = docShell->GetItemType(&docShellType);
|
||||
if (NS_SUCCEEDED(result)){
|
||||
if (nsIDocShellTreeItem::typeChrome == docShellType){
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nsContentUtils::IsInChromeDocshell(mDocument)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_attinasi
|
||||
printf("Setting Preference Style Rules:\n");
|
||||
#endif
|
||||
// if here, we need to create rules for the prefs
|
||||
// - this includes the background-color, the text-color,
|
||||
// the link color, the visited link color and the link-underlining
|
||||
|
||||
// first clear any exising rules
|
||||
nsresult result = ClearPreferenceStyleRules();
|
||||
|
||||
// now the link rules (must come after the color rules, or links will not be correct color!)
|
||||
// XXX - when there is both an override and agent pref stylesheet this won't matter,
|
||||
// as the color rules will be overrides and the links rules will be agent
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = SetPrefLinkRules();
|
||||
}
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
|
||||
#ifdef DEBUG_attinasi
|
||||
printf("Setting Preference Style Rules:\n");
|
||||
#endif
|
||||
// if here, we need to create rules for the prefs
|
||||
// - this includes the background-color, the text-color,
|
||||
// the link color, the visited link color and the link-underlining
|
||||
|
||||
// first clear any exising rules
|
||||
result = ClearPreferenceStyleRules();
|
||||
|
||||
// now the link rules (must come after the color rules, or links will not be correct color!)
|
||||
// XXX - when there is both an override and agent pref stylesheet this won't matter,
|
||||
// as the color rules will be overrides and the links rules will be agent
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = SetPrefLinkRules();
|
||||
}
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = SetPrefFocusRules();
|
||||
}
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = SetPrefNoScriptRule();
|
||||
}
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = SetPrefNoFramesRule();
|
||||
}
|
||||
result = SetPrefFocusRules();
|
||||
}
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = SetPrefNoScriptRule();
|
||||
}
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
result = SetPrefNoFramesRule();
|
||||
}
|
||||
#ifdef DEBUG_attinasi
|
||||
printf( "Preference Style Rules set: error=%ld\n", (long)result);
|
||||
@ -5488,7 +5474,11 @@ nsresult PresShell::RetargetEventToParent(nsGUIEvent* aEvent,
|
||||
// Now, find the parent pres shell and send the event there
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem =
|
||||
do_QueryInterface(container);
|
||||
NS_ASSERTION(treeItem, "No tree item for container.");
|
||||
if (!treeItem) {
|
||||
// Might have gone away, or never been around to start with
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
|
||||
treeItem->GetParent(getter_AddRefs(parentTreeItem));
|
||||
nsCOMPtr<nsIDocShell> parentDocShell =
|
||||
|
@ -306,7 +306,12 @@ nsFileControlFrame::MouseListener::MouseClick(nsIDOMEvent* aMouseEvent)
|
||||
if (!filePicker)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
result = filePicker->Init(doc->GetWindow(), title, nsIFilePicker::modeOpen);
|
||||
nsPIDOMWindow* win = doc->GetWindow();
|
||||
if (!win) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
result = filePicker->Init(win, title, nsIFilePicker::modeOpen);
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
|
||||
|
@ -84,9 +84,13 @@ GetDeviceContextFor(nsPresContext* aPresContext)
|
||||
// things right in multi-monitor situations.
|
||||
// (It's not clear if this is really needed for GetDepth and GetColor,
|
||||
// but do it anyway.)
|
||||
return nsLayoutUtils::GetDeviceContextForScreenInfo(
|
||||
nsIDeviceContext* ctx = nsLayoutUtils::GetDeviceContextForScreenInfo(
|
||||
nsCOMPtr<nsIDocShell>(do_QueryInterface(
|
||||
nsCOMPtr<nsISupports>(aPresContext->GetContainer()))));
|
||||
if (!ctx) {
|
||||
ctx = aPresContext->DeviceContext();
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(nsresult)
|
||||
|
@ -178,7 +178,9 @@ nsTitleBarFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
else {
|
||||
nsIPresShell* presShell = aPresContext->PresShell();
|
||||
nsPIDOMWindow *window = presShell->GetDocument()->GetWindow();
|
||||
window->MoveBy(nsMoveBy.x, nsMoveBy.y);
|
||||
if (window) {
|
||||
window->MoveBy(nsMoveBy.x, nsMoveBy.y);
|
||||
}
|
||||
}
|
||||
|
||||
*aEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
|
Loading…
Reference in New Issue
Block a user