Back to index

lightning-sunbird  0.9+nobinonly
nsSelectsAreaFrame.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Pierre Phaneuf <pp@ludusdesign.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 #include "nsSelectsAreaFrame.h"
00039 #include "nsCOMPtr.h"
00040 #include "nsIDOMHTMLOptionElement.h"
00041 #include "nsIContent.h"
00042 #include "nsListControlFrame.h"
00043 
00044 nsresult
00045 NS_NewSelectsAreaFrame(nsIPresShell* aShell, nsIFrame** aNewFrame, PRUint32 aFlags)
00046 {
00047   NS_PRECONDITION(aNewFrame, "null OUT ptr");
00048   if (nsnull == aNewFrame) {
00049     return NS_ERROR_NULL_POINTER;
00050   }
00051   nsSelectsAreaFrame* it = new (aShell) nsSelectsAreaFrame;
00052   if (nsnull == it) {
00053     return NS_ERROR_OUT_OF_MEMORY;
00054   }
00055   // We need NS_BLOCK_SPACE_MGR to ensure that the options inside the select
00056   // aren't expanded by right floats outside the select.
00057   it->SetFlags(aFlags | NS_BLOCK_SPACE_MGR);
00058   *aNewFrame = it;
00059   return NS_OK;
00060 }
00061 
00062 /*NS_IMETHODIMP
00063 nsSelectsAreaFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr)
00064 {
00065   if (NULL == aInstancePtr) {
00066     return NS_ERROR_NULL_POINTER;
00067   }
00068   if (aIID.Equals(kAreaFrameIID)) {
00069     nsIAreaFrame* tmp = (nsIAreaFrame*)this;
00070     *aInstancePtr = (void*)tmp;
00071     return NS_OK;
00072   }
00073   return nsAreaFrame::QueryInterface(aIID, aInstancePtr);
00074 }
00075 */
00076 
00077 //---------------------------------------------------------
00078 PRBool 
00079 nsSelectsAreaFrame::IsOptionElement(nsIContent* aContent)
00080 {
00081   PRBool result = PR_FALSE;
00082  
00083   nsCOMPtr<nsIDOMHTMLOptionElement> optElem;
00084   if (NS_SUCCEEDED(aContent->QueryInterface(NS_GET_IID(nsIDOMHTMLOptionElement),(void**) getter_AddRefs(optElem)))) {      
00085     if (optElem != nsnull) {
00086       result = PR_TRUE;
00087     }
00088   }
00089  
00090   return result;
00091 }
00092 
00093 //---------------------------------------------------------
00094 PRBool 
00095 nsSelectsAreaFrame::IsOptionElementFrame(nsIFrame *aFrame)
00096 {
00097   nsIContent *content = aFrame->GetContent();
00098   if (content) {
00099     return IsOptionElement(content);
00100   }
00101   return PR_FALSE;
00102 }
00103 
00104 //---------------------------------------------------------
00105 NS_IMETHODIMP
00106 nsSelectsAreaFrame::GetFrameForPoint(const nsPoint& aPoint,
00107                                      nsFramePaintLayer aWhichLayer,
00108                                      nsIFrame** aFrame)
00109 {
00110 
00111   PRBool inThisFrame = mRect.Contains(aPoint);
00112 
00113   if (!((mState & NS_FRAME_OUTSIDE_CHILDREN) || inThisFrame )) {
00114     return NS_ERROR_FAILURE;
00115   }
00116 
00117   nsresult result = nsAreaFrame::GetFrameForPoint(aPoint, aWhichLayer, aFrame);
00118 
00119   if (result == NS_OK) {
00120     nsIFrame* selectedFrame = *aFrame;
00121     while (selectedFrame && !IsOptionElementFrame(selectedFrame)) {
00122       selectedFrame = selectedFrame->GetParent();
00123     }  
00124     if (selectedFrame) {
00125       *aFrame = selectedFrame;
00126     }
00127     // else, keep the original result as *aFrame, which could be this frame
00128   }
00129 
00130   return result;
00131 }
00132 
00133 NS_IMETHODIMP
00134 nsSelectsAreaFrame::Paint(nsPresContext*      aPresContext,
00135                           nsIRenderingContext& aRenderingContext,
00136                           const nsRect&        aDirtyRect,
00137                           nsFramePaintLayer    aWhichLayer,
00138                           PRUint32             aFlags)
00139 {
00140   nsAreaFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, aFlags);
00141 
00142   nsIFrame* frame = this;
00143   while (frame) {
00144     frame = frame->GetParent();
00145     if (frame->GetType() == nsLayoutAtoms::listControlFrame) {
00146       nsListControlFrame* listFrame = NS_STATIC_CAST(nsListControlFrame*, frame);
00147       listFrame->PaintFocus(aRenderingContext, aWhichLayer);
00148       return NS_OK;
00149     }
00150   }
00151 
00152   return NS_OK;
00153 }