LCOV - code coverage report
Current view: directory - layout/mathml - nsMathMLmactionFrame.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 170 0 0.0 %
Date: 2012-06-02 Functions: 21 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is Mozilla MathML Project.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * The University Of Queensland.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1999
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Roger B. Sidje <rbs@maths.uq.edu.au>
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
      27                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #include "nsCOMPtr.h"
      40                 : #include "nsFrame.h"
      41                 : #include "nsPresContext.h"
      42                 : #include "nsStyleContext.h"
      43                 : #include "nsStyleConsts.h"
      44                 : #include "nsINameSpaceManager.h"
      45                 : 
      46                 : #include "nsCSSRendering.h"
      47                 : #include "prprf.h"         // For PR_snprintf()
      48                 : 
      49                 : #include "nsIDocShellTreeItem.h"
      50                 : #include "nsIDocShellTreeOwner.h"
      51                 : #include "nsIWebBrowserChrome.h"
      52                 : #include "nsIInterfaceRequestor.h"
      53                 : #include "nsIInterfaceRequestorUtils.h"
      54                 : #include "nsIDOMElement.h"
      55                 : 
      56                 : #include "nsIDOMEventTarget.h"
      57                 : 
      58                 : #include "nsMathMLmactionFrame.h"
      59                 : #include "nsAutoPtr.h"
      60                 : #include "nsStyleSet.h"
      61                 : #include "nsDisplayList.h"
      62                 : #include "nsContentUtils.h"
      63                 : 
      64                 : //
      65                 : // <maction> -- bind actions to a subexpression - implementation
      66                 : //
      67                 : 
      68                 : #define NS_MATHML_ACTION_TYPE_NONE         0
      69                 : #define NS_MATHML_ACTION_TYPE_TOGGLE       1
      70                 : #define NS_MATHML_ACTION_TYPE_STATUSLINE   2
      71                 : #define NS_MATHML_ACTION_TYPE_TOOLTIP      3 // unsupported
      72                 : 
      73                 : 
      74                 : nsIFrame*
      75               0 : NS_NewMathMLmactionFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
      76                 : {
      77               0 :   return new (aPresShell) nsMathMLmactionFrame(aContext);
      78                 : }
      79                 : 
      80               0 : NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmactionFrame)
      81                 : 
      82               0 : nsMathMLmactionFrame::~nsMathMLmactionFrame()
      83                 : {
      84                 :   // unregister us as a mouse event listener ...
      85                 :   //  printf("maction:%p unregistering as mouse event listener ...\n", this);
      86               0 :   if (mListener) {
      87               0 :     mContent->RemoveSystemEventListener(NS_LITERAL_STRING("click"), mListener,
      88               0 :                                         false);
      89               0 :     mContent->RemoveSystemEventListener(NS_LITERAL_STRING("mouseover"), mListener,
      90               0 :                                         false);
      91               0 :     mContent->RemoveSystemEventListener(NS_LITERAL_STRING("mouseout"), mListener,
      92               0 :                                         false);
      93                 :   }
      94               0 : }
      95                 : 
      96                 : NS_IMETHODIMP
      97               0 : nsMathMLmactionFrame::Init(nsIContent*      aContent,
      98                 :                            nsIFrame*        aParent,
      99                 :                            nsIFrame*        aPrevInFlow)
     100                 : {
     101               0 :   nsAutoString value, prefix;
     102                 : 
     103                 :   // Init our local attributes
     104                 : 
     105               0 :   mChildCount = -1; // these will be updated in GetSelectedFrame()
     106               0 :   mSelection = 0;
     107               0 :   mSelectedFrame = nsnull;
     108               0 :   nsRefPtr<nsStyleContext> newStyleContext;
     109                 : 
     110               0 :   mActionType = NS_MATHML_ACTION_TYPE_NONE;
     111               0 :   aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::actiontype_, value);
     112               0 :   if (!value.IsEmpty()) {
     113               0 :     if (value.EqualsLiteral("toggle"))
     114               0 :       mActionType = NS_MATHML_ACTION_TYPE_TOGGLE;
     115                 : 
     116                 :     // XXX use goto to jump out of these if?
     117                 : 
     118               0 :     if (NS_MATHML_ACTION_TYPE_NONE == mActionType) {
     119                 :       // expected tooltip prefix (8ch)...
     120               0 :       if (8 < value.Length() && 0 == value.Find("tooltip#"))
     121               0 :         mActionType = NS_MATHML_ACTION_TYPE_TOOLTIP;
     122                 :     }
     123                 : 
     124               0 :     if (NS_MATHML_ACTION_TYPE_NONE == mActionType) {
     125                 :       // expected statusline prefix (11ch)...
     126               0 :       if (11 < value.Length() && 0 == value.Find("statusline#"))
     127               0 :         mActionType = NS_MATHML_ACTION_TYPE_STATUSLINE;
     128                 :     }
     129                 : 
     130                 :   }
     131                 : 
     132                 :   // Let the base class do the rest
     133               0 :   return nsMathMLContainerFrame::Init(aContent, aParent, aPrevInFlow);
     134                 : }
     135                 : 
     136                 : NS_IMETHODIMP
     137               0 : nsMathMLmactionFrame::TransmitAutomaticData() {
     138                 :   // The REC defines the following element to be space-like:
     139                 :   // * an maction element whose selected sub-expression exists and is
     140                 :   //   space-like;
     141               0 :   nsIMathMLFrame* mathMLFrame = do_QueryFrame(mSelectedFrame);
     142               0 :   if (mathMLFrame && mathMLFrame->IsSpaceLike()) {
     143               0 :     mPresentationData.flags |= NS_MATHML_SPACE_LIKE;
     144                 :   } else {
     145               0 :     mPresentationData.flags &= ~NS_MATHML_SPACE_LIKE;
     146                 :   }
     147                 : 
     148                 :   // The REC defines the following element to be an embellished operator:
     149                 :   // * an maction element whose selected sub-expression exists and is an
     150                 :   //   embellished operator;
     151               0 :   mPresentationData.baseFrame = mSelectedFrame;
     152               0 :   GetEmbellishDataFrom(mSelectedFrame, mEmbellishData);
     153                 : 
     154               0 :   return NS_OK;
     155                 : }
     156                 : 
     157                 : nsresult
     158               0 : nsMathMLmactionFrame::ChildListChanged(PRInt32 aModType)
     159                 : {
     160                 :   // update cached values
     161               0 :   mChildCount = -1;
     162               0 :   mSelection = 0;
     163               0 :   mSelectedFrame = nsnull;
     164               0 :   GetSelectedFrame();
     165                 : 
     166               0 :   return nsMathMLContainerFrame::ChildListChanged(aModType);
     167                 : }
     168                 : 
     169                 : // return the frame whose number is given by the attribute selection="number"
     170                 : nsIFrame* 
     171               0 : nsMathMLmactionFrame::GetSelectedFrame()
     172                 : {
     173               0 :   nsAutoString value;
     174                 :   PRInt32 selection; 
     175                 : 
     176                 :   GetAttribute(mContent, mPresentationData.mstyle, nsGkAtoms::selection_,
     177               0 :                value);
     178               0 :   if (!value.IsEmpty()) {
     179                 :     PRInt32 errorCode;
     180               0 :     selection = value.ToInteger(&errorCode);
     181               0 :     if (NS_FAILED(errorCode)) 
     182               0 :       selection = 1;
     183                 :   }
     184               0 :   else selection = 1; // default is first frame
     185                 : 
     186               0 :   if (-1 != mChildCount) { // we have been in this function before...
     187                 :     // cater for invalid user-supplied selection
     188               0 :     if (selection > mChildCount || selection < 1) 
     189               0 :       selection = 1;
     190                 :     // quick return if it is identical with our cache
     191               0 :     if (selection == mSelection) 
     192               0 :       return mSelectedFrame;
     193                 :   }
     194                 : 
     195                 :   // get the selected child and cache new values...
     196               0 :   PRInt32 count = 0;
     197               0 :   nsIFrame* childFrame = mFrames.FirstChild();
     198               0 :   while (childFrame) {
     199               0 :     if (!mSelectedFrame) 
     200               0 :       mSelectedFrame = childFrame; // default is first child
     201               0 :     if (++count == selection) 
     202               0 :       mSelectedFrame = childFrame;
     203                 : 
     204               0 :     childFrame = childFrame->GetNextSibling();
     205                 :   }
     206                 :   // cater for invalid user-supplied selection
     207               0 :   if (selection > count || selection < 1) 
     208               0 :     selection = 1;
     209                 : 
     210               0 :   mChildCount = count;
     211               0 :   mSelection = selection;
     212                 : 
     213               0 :   return mSelectedFrame;
     214                 : }
     215                 : 
     216                 : NS_IMETHODIMP
     217               0 : nsMathMLmactionFrame::SetInitialChildList(ChildListID     aListID,
     218                 :                                           nsFrameList&    aChildList)
     219                 : {
     220               0 :   nsresult rv = nsMathMLContainerFrame::SetInitialChildList(aListID, aChildList);
     221                 : 
     222                 :   // This very first call to GetSelectedFrame() will cause us to be marked as an
     223                 :   // embellished operator if the selected child is an embellished operator
     224               0 :   if (!GetSelectedFrame()) {
     225               0 :     mActionType = NS_MATHML_ACTION_TYPE_NONE;
     226                 :   }
     227                 :   else {
     228                 :     // create mouse event listener and register it
     229               0 :     mListener = new nsMathMLmactionFrame::MouseListener(this);
     230                 :     // printf("maction:%p registering as mouse event listener ...\n", this);
     231               0 :     mContent->AddSystemEventListener(NS_LITERAL_STRING("click"), mListener,
     232               0 :                                      false, false);
     233               0 :     mContent->AddSystemEventListener(NS_LITERAL_STRING("mouseover"), mListener,
     234               0 :                                      false, false);
     235               0 :     mContent->AddSystemEventListener(NS_LITERAL_STRING("mouseout"), mListener,
     236               0 :                                      false, false);
     237                 :   }
     238               0 :   return rv;
     239                 : }
     240                 : 
     241                 : //  Only paint the selected child...
     242                 : NS_IMETHODIMP
     243               0 : nsMathMLmactionFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
     244                 :                                        const nsRect&           aDirtyRect,
     245                 :                                        const nsDisplayListSet& aLists)
     246                 : {
     247               0 :   nsresult rv = DisplayBorderBackgroundOutline(aBuilder, aLists);
     248               0 :   NS_ENSURE_SUCCESS(rv, rv);
     249                 : 
     250               0 :   nsIFrame* childFrame = GetSelectedFrame();
     251               0 :   if (childFrame) {
     252                 :     // Put the child's background directly onto the content list
     253               0 :     nsDisplayListSet set(aLists, aLists.Content());
     254                 :     // The children should be in content order
     255               0 :     rv = BuildDisplayListForChild(aBuilder, childFrame, aDirtyRect, set);
     256               0 :     NS_ENSURE_SUCCESS(rv, rv);
     257                 :   }
     258                 : 
     259                 : #if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
     260                 :   // visual debug
     261                 :   rv = DisplayBoundingMetrics(aBuilder, this, mReference, mBoundingMetrics, aLists);
     262                 : #endif
     263               0 :   return rv;
     264                 : }
     265                 : 
     266                 : // Only reflow the selected child ...
     267                 : NS_IMETHODIMP
     268               0 : nsMathMLmactionFrame::Reflow(nsPresContext*          aPresContext,
     269                 :                              nsHTMLReflowMetrics&     aDesiredSize,
     270                 :                              const nsHTMLReflowState& aReflowState,
     271                 :                              nsReflowStatus&          aStatus)
     272                 : {
     273               0 :   nsresult rv = NS_OK;
     274               0 :   aStatus = NS_FRAME_COMPLETE;
     275               0 :   aDesiredSize.width = aDesiredSize.height = 0;
     276               0 :   aDesiredSize.ascent = 0;
     277               0 :   mBoundingMetrics = nsBoundingMetrics();
     278               0 :   nsIFrame* childFrame = GetSelectedFrame();
     279               0 :   if (childFrame) {
     280               0 :     nsSize availSize(aReflowState.ComputedWidth(), NS_UNCONSTRAINEDSIZE);
     281                 :     nsHTMLReflowState childReflowState(aPresContext, aReflowState,
     282               0 :                                        childFrame, availSize);
     283                 :     rv = ReflowChild(childFrame, aPresContext, aDesiredSize,
     284               0 :                      childReflowState, aStatus);
     285                 :     SaveReflowAndBoundingMetricsFor(childFrame, aDesiredSize,
     286               0 :                                     aDesiredSize.mBoundingMetrics);
     287               0 :     mBoundingMetrics = aDesiredSize.mBoundingMetrics;
     288                 :   }
     289               0 :   FinalizeReflow(*aReflowState.rendContext, aDesiredSize);
     290               0 :   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
     291               0 :   return rv;
     292                 : }
     293                 : 
     294                 : // Only place the selected child ...
     295                 : /* virtual */ nsresult
     296               0 : nsMathMLmactionFrame::Place(nsRenderingContext& aRenderingContext,
     297                 :                             bool                 aPlaceOrigin,
     298                 :                             nsHTMLReflowMetrics& aDesiredSize)
     299                 : {
     300               0 :   aDesiredSize.width = aDesiredSize.height = 0;
     301               0 :   aDesiredSize.ascent = 0;
     302               0 :   mBoundingMetrics = nsBoundingMetrics();
     303               0 :   nsIFrame* childFrame = GetSelectedFrame();
     304               0 :   if (childFrame) {
     305               0 :     GetReflowAndBoundingMetricsFor(childFrame, aDesiredSize, mBoundingMetrics);
     306               0 :     if (aPlaceOrigin) {
     307               0 :       FinishReflowChild(childFrame, PresContext(), nsnull, aDesiredSize, 0, 0, 0);
     308                 :     }
     309               0 :     mReference.x = 0;
     310               0 :     mReference.y = aDesiredSize.ascent;
     311                 :   }
     312               0 :   aDesiredSize.mBoundingMetrics = mBoundingMetrics;
     313               0 :   return NS_OK;
     314                 : }
     315                 : 
     316                 : // ################################################################
     317                 : // Event handlers 
     318                 : // ################################################################
     319                 : 
     320               0 : NS_IMPL_ISUPPORTS1(nsMathMLmactionFrame::MouseListener,
     321                 :                    nsIDOMEventListener)
     322                 : 
     323                 : 
     324                 : // helper to show a msg on the status bar
     325                 : // curled from nsObjectFrame.cpp ...
     326                 : void
     327               0 : ShowStatus(nsPresContext* aPresContext, nsString& aStatusMsg)
     328                 : {
     329               0 :   nsCOMPtr<nsISupports> cont = aPresContext->GetContainer();
     330               0 :   if (cont) {
     331               0 :     nsCOMPtr<nsIDocShellTreeItem> docShellItem(do_QueryInterface(cont));
     332               0 :     if (docShellItem) {
     333               0 :       nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
     334               0 :       docShellItem->GetTreeOwner(getter_AddRefs(treeOwner));
     335               0 :       if (treeOwner) {
     336               0 :         nsCOMPtr<nsIWebBrowserChrome> browserChrome(do_GetInterface(treeOwner));
     337               0 :         if (browserChrome) {
     338               0 :           browserChrome->SetStatus(nsIWebBrowserChrome::STATUS_LINK, aStatusMsg.get());
     339                 :         }
     340                 :       }
     341                 :     }
     342                 :   }
     343               0 : }
     344                 : 
     345                 : NS_IMETHODIMP
     346               0 : nsMathMLmactionFrame::MouseListener::HandleEvent(nsIDOMEvent* aEvent)
     347                 : {
     348               0 :   nsAutoString eventType;
     349               0 :   aEvent->GetType(eventType);
     350               0 :   if (eventType.EqualsLiteral("mouseover")) {
     351               0 :     mOwner->MouseOver();
     352                 :   }
     353               0 :   else if (eventType.EqualsLiteral("click")) {
     354               0 :     mOwner->MouseClick();
     355                 :   }
     356               0 :   else if (eventType.EqualsLiteral("mouseout")) {
     357               0 :     mOwner->MouseOut();
     358                 :   }
     359                 :   else {
     360               0 :     NS_ABORT();
     361                 :   }
     362                 : 
     363               0 :   return NS_OK;
     364                 : }
     365                 : 
     366                 : void
     367               0 : nsMathMLmactionFrame::MouseOver()
     368                 : {
     369                 :   // see if we should display a status message
     370               0 :   if (NS_MATHML_ACTION_TYPE_STATUSLINE == mActionType) {
     371               0 :     nsAutoString value;
     372               0 :     mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::actiontype_, value);
     373                 :     // expected statusline prefix (11ch)...
     374               0 :     if (11 < value.Length() && 0 == value.Find("statusline#")) {
     375               0 :       value.Cut(0, 11);
     376               0 :       ShowStatus(PresContext(), value);
     377                 :     }
     378                 :   }
     379               0 : }
     380                 : 
     381                 : void
     382               0 : nsMathMLmactionFrame::MouseOut()
     383                 : {
     384                 :   // see if we should remove the status message
     385               0 :   if (NS_MATHML_ACTION_TYPE_STATUSLINE == mActionType) {
     386               0 :     nsAutoString value;
     387               0 :     value.SetLength(0);
     388               0 :     ShowStatus(PresContext(), value);
     389                 :   }
     390               0 : }
     391                 : 
     392                 : void
     393               0 : nsMathMLmactionFrame::MouseClick()
     394                 : {
     395               0 :   if (NS_MATHML_ACTION_TYPE_TOGGLE == mActionType) {
     396               0 :     if (mChildCount > 1) {
     397               0 :       PRInt32 selection = (mSelection == mChildCount)? 1 : mSelection + 1;
     398               0 :       nsAutoString value;
     399                 :       char cbuf[10];
     400               0 :       PR_snprintf(cbuf, sizeof(cbuf), "%d", selection);
     401               0 :       value.AssignASCII(cbuf);
     402               0 :       bool notify = false; // don't yet notify the document
     403               0 :       mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::selection_, value, notify);
     404                 : 
     405                 :       // Now trigger a content-changed reflow...
     406               0 :       PresContext()->PresShell()->
     407                 :         FrameNeedsReflow(mSelectedFrame, nsIPresShell::eTreeChange,
     408               0 :                          NS_FRAME_IS_DIRTY);
     409                 :     }
     410                 :   }
     411               0 : }

Generated by: LCOV version 1.7