LCOV - code coverage report
Current view: top level - layout/mathml - nsMathMLmactionFrame.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 154 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 18 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "nsMathMLmactionFrame.h"
       7             : #include "nsCOMPtr.h"
       8             : #include "nsPresContext.h"
       9             : #include "nsNameSpaceManager.h"
      10             : #include "nsIDocShell.h"
      11             : #include "nsIDocShellTreeOwner.h"
      12             : #include "nsIWebBrowserChrome.h"
      13             : #include "nsIInterfaceRequestorUtils.h"
      14             : #include "nsTextFragment.h"
      15             : #include "nsIDOMEvent.h"
      16             : #include "mozilla/gfx/2D.h"
      17             : 
      18             : //
      19             : // <maction> -- bind actions to a subexpression - implementation
      20             : //
      21             : 
      22             : enum nsMactionActionTypes {
      23             :   NS_MATHML_ACTION_TYPE_CLASS_ERROR            = 0x10,
      24             :   NS_MATHML_ACTION_TYPE_CLASS_USE_SELECTION    = 0x20,
      25             :   NS_MATHML_ACTION_TYPE_CLASS_IGNORE_SELECTION = 0x40,
      26             :   NS_MATHML_ACTION_TYPE_CLASS_BITMASK          = 0xF0,
      27             : 
      28             :   NS_MATHML_ACTION_TYPE_NONE       = NS_MATHML_ACTION_TYPE_CLASS_ERROR|0x01,
      29             : 
      30             :   NS_MATHML_ACTION_TYPE_TOGGLE     = NS_MATHML_ACTION_TYPE_CLASS_USE_SELECTION|0x01,
      31             :   NS_MATHML_ACTION_TYPE_UNKNOWN    = NS_MATHML_ACTION_TYPE_CLASS_USE_SELECTION|0x02,
      32             : 
      33             :   NS_MATHML_ACTION_TYPE_STATUSLINE = NS_MATHML_ACTION_TYPE_CLASS_IGNORE_SELECTION|0x01,
      34             :   NS_MATHML_ACTION_TYPE_TOOLTIP    = NS_MATHML_ACTION_TYPE_CLASS_IGNORE_SELECTION|0x02
      35             : };
      36             : 
      37             : 
      38             : // helper function to parse actiontype attribute
      39             : static int32_t
      40           0 : GetActionType(nsIContent* aContent)
      41             : {
      42           0 :   nsAutoString value;
      43             : 
      44           0 :   if (aContent) {
      45           0 :     if (!aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::actiontype_, value))
      46           0 :       return NS_MATHML_ACTION_TYPE_NONE;
      47             :   }
      48             : 
      49           0 :   if (value.EqualsLiteral("toggle"))
      50           0 :     return NS_MATHML_ACTION_TYPE_TOGGLE;
      51           0 :   if (value.EqualsLiteral("statusline"))
      52           0 :     return NS_MATHML_ACTION_TYPE_STATUSLINE;
      53           0 :   if (value.EqualsLiteral("tooltip"))
      54           0 :     return NS_MATHML_ACTION_TYPE_TOOLTIP;
      55             : 
      56           0 :   return NS_MATHML_ACTION_TYPE_UNKNOWN;
      57             : }
      58             : 
      59             : nsIFrame*
      60           0 : NS_NewMathMLmactionFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
      61             : {
      62           0 :   return new (aPresShell) nsMathMLmactionFrame(aContext);
      63             : }
      64             : 
      65           0 : NS_IMPL_FRAMEARENA_HELPERS(nsMathMLmactionFrame)
      66             : 
      67           0 : nsMathMLmactionFrame::~nsMathMLmactionFrame()
      68             : {
      69             :   // unregister us as a mouse event listener ...
      70             :   //  printf("maction:%p unregistering as mouse event listener ...\n", this);
      71           0 :   if (mListener) {
      72           0 :     mContent->RemoveSystemEventListener(NS_LITERAL_STRING("click"), mListener,
      73           0 :                                         false);
      74           0 :     mContent->RemoveSystemEventListener(NS_LITERAL_STRING("mouseover"), mListener,
      75           0 :                                         false);
      76           0 :     mContent->RemoveSystemEventListener(NS_LITERAL_STRING("mouseout"), mListener,
      77           0 :                                         false);
      78             :   }
      79           0 : }
      80             : 
      81             : void
      82           0 : nsMathMLmactionFrame::Init(nsIContent*       aContent,
      83             :                            nsContainerFrame* aParent,
      84             :                            nsIFrame*         aPrevInFlow)
      85             : {
      86             :   // Init our local attributes
      87             : 
      88           0 :   mChildCount = -1; // these will be updated in GetSelectedFrame()
      89           0 :   mActionType = GetActionType(aContent);
      90             : 
      91             :   // Let the base class do the rest
      92           0 :   return nsMathMLSelectedFrame::Init(aContent, aParent, aPrevInFlow);
      93             : }
      94             : 
      95             : nsresult
      96           0 : nsMathMLmactionFrame::ChildListChanged(int32_t aModType)
      97             : {
      98             :   // update cached values
      99           0 :   mChildCount = -1;
     100           0 :   mSelectedFrame = nullptr;
     101             : 
     102           0 :   return nsMathMLSelectedFrame::ChildListChanged(aModType);
     103             : }
     104             : 
     105             : // return the frame whose number is given by the attribute selection="number"
     106             : nsIFrame*
     107           0 : nsMathMLmactionFrame::GetSelectedFrame()
     108             : {
     109           0 :   nsAutoString value;
     110             :   int32_t selection;
     111             : 
     112           0 :   if ((mActionType & NS_MATHML_ACTION_TYPE_CLASS_BITMASK) ==
     113             :        NS_MATHML_ACTION_TYPE_CLASS_ERROR) {
     114           0 :     mSelection = -1;
     115           0 :     mInvalidMarkup = true;
     116           0 :     mSelectedFrame = nullptr;
     117           0 :     return mSelectedFrame;
     118             :   }
     119             : 
     120             :   // Selection is not applied to tooltip and statusline.
     121             :   // Thereby return the first child.
     122           0 :   if ((mActionType & NS_MATHML_ACTION_TYPE_CLASS_BITMASK) ==
     123             :        NS_MATHML_ACTION_TYPE_CLASS_IGNORE_SELECTION) {
     124             :     // We don't touch mChildCount here. It's incorrect to assign it 1,
     125             :     // and it's inefficient to count the children. It's fine to leave
     126             :     // it be equal -1 because it's not used with other actiontypes.
     127           0 :     mSelection = 1;
     128           0 :     mInvalidMarkup = false;
     129           0 :     mSelectedFrame = mFrames.FirstChild();
     130           0 :     return mSelectedFrame;
     131             :   }
     132             : 
     133           0 :   mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::selection_, value);
     134           0 :   if (!value.IsEmpty()) {
     135             :     nsresult errorCode;
     136           0 :     selection = value.ToInteger(&errorCode);
     137           0 :     if (NS_FAILED(errorCode))
     138           0 :       selection = 1;
     139             :   }
     140           0 :   else selection = 1; // default is first frame
     141             : 
     142           0 :   if (-1 != mChildCount) { // we have been in this function before...
     143             :     // cater for invalid user-supplied selection
     144           0 :     if (selection > mChildCount || selection < 1)
     145           0 :       selection = -1;
     146             :     // quick return if it is identical with our cache
     147           0 :     if (selection == mSelection)
     148           0 :       return mSelectedFrame;
     149             :   }
     150             : 
     151             :   // get the selected child and cache new values...
     152           0 :   int32_t count = 0;
     153           0 :   nsIFrame* childFrame = mFrames.FirstChild();
     154           0 :   while (childFrame) {
     155           0 :     if (!mSelectedFrame)
     156           0 :       mSelectedFrame = childFrame; // default is first child
     157           0 :     if (++count == selection)
     158           0 :       mSelectedFrame = childFrame;
     159             : 
     160           0 :     childFrame = childFrame->GetNextSibling();
     161             :   }
     162             :   // cater for invalid user-supplied selection
     163           0 :   if (selection > count || selection < 1)
     164           0 :     selection = -1;
     165             : 
     166           0 :   mChildCount = count;
     167           0 :   mSelection = selection;
     168           0 :   mInvalidMarkup = (mSelection == -1);
     169           0 :   TransmitAutomaticData();
     170             : 
     171           0 :   return mSelectedFrame;
     172             : }
     173             : 
     174             : void
     175           0 : nsMathMLmactionFrame::SetInitialChildList(ChildListID     aListID,
     176             :                                           nsFrameList&    aChildList)
     177             : {
     178           0 :   nsMathMLSelectedFrame::SetInitialChildList(aListID, aChildList);
     179             : 
     180           0 :   if (!mSelectedFrame) {
     181           0 :     mActionType = NS_MATHML_ACTION_TYPE_NONE;
     182             :   }
     183             :   else {
     184             :     // create mouse event listener and register it
     185           0 :     mListener = new nsMathMLmactionFrame::MouseListener(this);
     186             :     // printf("maction:%p registering as mouse event listener ...\n", this);
     187           0 :     mContent->AddSystemEventListener(NS_LITERAL_STRING("click"), mListener,
     188           0 :                                      false, false);
     189           0 :     mContent->AddSystemEventListener(NS_LITERAL_STRING("mouseover"), mListener,
     190           0 :                                      false, false);
     191           0 :     mContent->AddSystemEventListener(NS_LITERAL_STRING("mouseout"), mListener,
     192           0 :                                      false, false);
     193             :   }
     194           0 : }
     195             : 
     196             : nsresult
     197           0 : nsMathMLmactionFrame::AttributeChanged(int32_t  aNameSpaceID,
     198             :                                        nsIAtom* aAttribute,
     199             :                                        int32_t  aModType)
     200             : {
     201           0 :   bool needsReflow = false;
     202             : 
     203           0 :   if (aAttribute == nsGkAtoms::actiontype_) {
     204             :     // updating mActionType ...
     205           0 :     int32_t oldActionType = mActionType;
     206           0 :     mActionType = GetActionType(mContent);
     207             : 
     208             :     // Initiate a reflow when actiontype classes are different.
     209           0 :     if ((oldActionType & NS_MATHML_ACTION_TYPE_CLASS_BITMASK) !=
     210           0 :           (mActionType & NS_MATHML_ACTION_TYPE_CLASS_BITMASK)) {
     211           0 :       needsReflow = true;
     212             :     }
     213           0 :   } else if (aAttribute == nsGkAtoms::selection_) {
     214           0 :     if ((mActionType & NS_MATHML_ACTION_TYPE_CLASS_BITMASK) ==
     215             :          NS_MATHML_ACTION_TYPE_CLASS_USE_SELECTION) {
     216           0 :       needsReflow = true;
     217             :     }
     218             :   } else {
     219             :     // let the base class handle other attribute changes
     220             :     return
     221           0 :       nsMathMLContainerFrame::AttributeChanged(aNameSpaceID,
     222           0 :                                                aAttribute, aModType);
     223             :   }
     224             : 
     225           0 :   if (needsReflow) {
     226           0 :     PresContext()->PresShell()->
     227           0 :       FrameNeedsReflow(this, nsIPresShell::eTreeChange, NS_FRAME_IS_DIRTY);
     228             :   }
     229             : 
     230           0 :   return NS_OK;
     231             : }
     232             : 
     233             : // ################################################################
     234             : // Event handlers
     235             : // ################################################################
     236             : 
     237           0 : NS_IMPL_ISUPPORTS(nsMathMLmactionFrame::MouseListener,
     238             :                   nsIDOMEventListener)
     239             : 
     240             : 
     241             : // helper to show a msg on the status bar
     242             : // curled from nsPluginFrame.cpp ...
     243             : void
     244           0 : ShowStatus(nsPresContext* aPresContext, nsString& aStatusMsg)
     245             : {
     246           0 :   nsCOMPtr<nsIDocShellTreeItem> docShellItem(aPresContext->GetDocShell());
     247           0 :   if (docShellItem) {
     248           0 :     nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
     249           0 :     docShellItem->GetTreeOwner(getter_AddRefs(treeOwner));
     250           0 :     if (treeOwner) {
     251           0 :       nsCOMPtr<nsIWebBrowserChrome> browserChrome(do_GetInterface(treeOwner));
     252           0 :       if (browserChrome) {
     253           0 :         browserChrome->SetStatus(nsIWebBrowserChrome::STATUS_LINK, aStatusMsg.get());
     254             :       }
     255             :     }
     256             :   }
     257           0 : }
     258             : 
     259             : NS_IMETHODIMP
     260           0 : nsMathMLmactionFrame::MouseListener::HandleEvent(nsIDOMEvent* aEvent)
     261             : {
     262           0 :   nsAutoString eventType;
     263           0 :   aEvent->GetType(eventType);
     264           0 :   if (eventType.EqualsLiteral("mouseover")) {
     265           0 :     mOwner->MouseOver();
     266             :   }
     267           0 :   else if (eventType.EqualsLiteral("click")) {
     268           0 :     mOwner->MouseClick();
     269             :   }
     270           0 :   else if (eventType.EqualsLiteral("mouseout")) {
     271           0 :     mOwner->MouseOut();
     272             :   }
     273             :   else {
     274           0 :     NS_ABORT();
     275             :   }
     276             : 
     277           0 :   return NS_OK;
     278             : }
     279             : 
     280             : void
     281           0 : nsMathMLmactionFrame::MouseOver()
     282             : {
     283             :   // see if we should display a status message
     284           0 :   if (NS_MATHML_ACTION_TYPE_STATUSLINE == mActionType) {
     285             :     // retrieve content from a second child if it exists
     286           0 :     nsIFrame* childFrame = mFrames.FrameAt(1);
     287           0 :     if (!childFrame) return;
     288             : 
     289           0 :     nsIContent* content = childFrame->GetContent();
     290           0 :     if (!content) return;
     291             : 
     292             :     // check whether the content is mtext or not
     293           0 :     if (content->IsMathMLElement(nsGkAtoms::mtext_)) {
     294             :       // get the text to be displayed
     295           0 :       content = content->GetFirstChild();
     296           0 :       if (!content) return;
     297             : 
     298           0 :       const nsTextFragment* textFrg = content->GetText();
     299           0 :       if (!textFrg) return;
     300             : 
     301           0 :       nsAutoString text;
     302           0 :       textFrg->AppendTo(text);
     303             :       // collapse whitespaces as listed in REC, section 3.2.6.1
     304           0 :       text.CompressWhitespace();
     305           0 :       ShowStatus(PresContext(), text);
     306             :     }
     307             :   }
     308             : }
     309             : 
     310             : void
     311           0 : nsMathMLmactionFrame::MouseOut()
     312             : {
     313             :   // see if we should remove the status message
     314           0 :   if (NS_MATHML_ACTION_TYPE_STATUSLINE == mActionType) {
     315           0 :     nsAutoString value;
     316           0 :     value.SetLength(0);
     317           0 :     ShowStatus(PresContext(), value);
     318             :   }
     319           0 : }
     320             : 
     321             : void
     322           0 : nsMathMLmactionFrame::MouseClick()
     323             : {
     324           0 :   if (NS_MATHML_ACTION_TYPE_TOGGLE == mActionType) {
     325           0 :     if (mChildCount > 1) {
     326           0 :       int32_t selection = (mSelection == mChildCount)? 1 : mSelection + 1;
     327           0 :       nsAutoString value;
     328           0 :       value.AppendInt(selection);
     329           0 :       bool notify = false; // don't yet notify the document
     330           0 :       mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::selection_, value, notify);
     331             : 
     332             :       // Now trigger a content-changed reflow...
     333           0 :       PresContext()->PresShell()->
     334           0 :         FrameNeedsReflow(mSelectedFrame, nsIPresShell::eTreeChange,
     335           0 :                          NS_FRAME_IS_DIRTY);
     336             :     }
     337             :   }
     338           0 : }

Generated by: LCOV version 1.13