~ubuntu-branches/ubuntu/intrepid/xulrunner-1.9/intrepid

« back to all changes in this revision

Viewing changes to mozilla/layout/mathml/base/src/nsMathMLmactionFrame.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Sack, Alexander Sack, Fabien Tassin
  • Date: 2008-02-13 11:47:21 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20080213114721-7om0mgzngvuk9czv
Tags: 1.9~b3+nobinonly-0ubuntu1
* release FIREFOX_3_0b3_RELEASE

[ Alexander Sack ]
* submit patch that ships xpcshell to bugzilla
  - rename debian/patches/ship_xpcshell.patch =>
           debian/patches/bz410617_att295212_ship_xpcshell.patch
  - update debian/patches/series
* fix tooltip in epiphany: previously displayed out of screen bounds
  (LP: #37507)
  - add debian/patches/bz233371_att297343_fix_outofscreen_embed_tooltip.patch
  - update debian/patches/series
* use default upstream gcc tweaks for improved performance - especially of the
  javascript engine
  - update debian/rules
* update global extension/plugin patch to apply cleanly against latest code
  - update debian/patches/bzXXX_gre_extension_plugin_support.patch
* fix pyxpcom build failure introduced by recent commit
  - add debian/patches/bzXXX_fix_pyxpcom_build_failure.patch
  - update debian/patches/series
* add distro independent global install locations for extensions,
  /usr/lib/mozilla/extensions and /usr/share/mozilla/extensions
  - update debian/xulrunner-1.9.dirs
* support embedded tarball layout when either there is a *.tar.bz2 in orig tarball
  or if DEBIAN_MOZCLIENT_EMBEDDED is not unset (you will need this to produce embedded
  tarballs during |get-orig-source|
  - update debian/rules
* bump minimum libnss3-dev build requirements to >= 3.12.0~1.9b3
  - update debian/control
* bump minimum libnspr4-dev build requirements to >= 4.7.0~1.9b3
  - update debian/control

[ Fabien Tassin ]
* Drop patches applied upstream
  - drop debian/patches/bz410617_att295212_ship_xpcshell.patch
  - drop debian/patches/bz404634_att294921.patch
  - drop debian/patches/bz386610_python2.5_ftbfs_amd64.patch
  - drop debian/patches/bz373918_att295042.patch
  - drop debian/patches/bz408062_unstable_pc.patch
  - drop debian/patches/bz384304_fix_recursive_symlinks.patch
  - update debian/patches/series
* Refresh diverged patches:
  - update debian/patches/bzXXX_pc_honour_system_nspr_nss.patch
  - update debian/patches/rename_venkman_addon.patch
  - update debian/patches/bz344818_cairo_xrender.patch
* Install links for all .so libs in the -dev package
  - update debian/patches/dont_install_so_in_dev.patch
* Bump gtk requirement to 2.12 as per Mozilla bug 412432
  - update debian/control
* Add #DEBHELPER# token to postinst/prerm scripts
  - update debian/xulrunner-1.9.{postinst,prerm}
* Install previously missed libdbusservice.so
  - update debian/xulrunner-1.9.install
* Update venkman patch to also rename locales
  - update debian/patches/rename_venkman_addon.patch
* Bump requirement for system cairo to >= 1.5.8 as we now need
  the newly added cairo_path_extents()
  - update debian/rules
* Include mozilla-devscripts file using -include so ifneq could be omitted
  - update debian/rules
* Fix missing .so symlinks regression
  - update debian/patches/dont_install_so_in_dev.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 "nsUnitConversion.h"
43
 
#include "nsStyleContext.h"
44
 
#include "nsStyleConsts.h"
45
 
#include "nsINameSpaceManager.h"
46
 
#include "nsIRenderingContext.h"
47
 
#include "nsIFontMetrics.h"
48
 
 
49
 
#include "nsCSSRendering.h"
50
 
#include "prprf.h"         // For PR_snprintf()
51
 
 
52
 
#include "nsIDocShellTreeItem.h"
53
 
#include "nsIDocShellTreeOwner.h"
54
 
#include "nsIWebBrowserChrome.h"
55
 
#include "nsIInterfaceRequestor.h"
56
 
#include "nsIInterfaceRequestorUtils.h"
57
 
#include "nsIDOMElement.h"
58
 
 
59
 
#include "nsIDOMEventTarget.h"
60
 
#include "nsIDOMMouseListener.h"
61
 
 
62
 
#include "nsMathMLmactionFrame.h"
63
 
#include "nsAutoPtr.h"
64
 
#include "nsStyleSet.h"
65
 
#include "nsDisplayList.h"
66
 
#include "nsContentUtils.h"
67
 
 
68
 
//
69
 
// <maction> -- bind actions to a subexpression - implementation
70
 
//
71
 
 
72
 
#define NS_MATHML_ACTION_TYPE_NONE         0
73
 
#define NS_MATHML_ACTION_TYPE_TOGGLE       1
74
 
#define NS_MATHML_ACTION_TYPE_STATUSLINE   2
75
 
#define NS_MATHML_ACTION_TYPE_TOOLTIP      3 // unsupported
76
 
#define NS_MATHML_ACTION_TYPE_RESTYLE      4
77
 
 
78
 
NS_IMPL_ADDREF_INHERITED(nsMathMLmactionFrame, nsMathMLContainerFrame)
79
 
NS_IMPL_RELEASE_INHERITED(nsMathMLmactionFrame, nsMathMLContainerFrame)
80
 
NS_IMPL_QUERY_INTERFACE_INHERITED1(nsMathMLmactionFrame, nsMathMLContainerFrame, nsIDOMMouseListener)
81
 
 
82
 
nsIFrame*
83
 
NS_NewMathMLmactionFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
84
 
{
85
 
  return new (aPresShell) nsMathMLmactionFrame(aContext);
86
 
}
87
 
 
88
 
nsMathMLmactionFrame::~nsMathMLmactionFrame()
89
 
{
90
 
  // unregister us as a mouse event listener ...
91
 
  //  printf("maction:%p unregistering as mouse event listener ...\n", this);
92
 
  mContent->RemoveEventListenerByIID(this, NS_GET_IID(nsIDOMMouseListener));
93
 
}
94
 
 
95
 
NS_IMETHODIMP
96
 
nsMathMLmactionFrame::Init(nsIContent*      aContent,
97
 
                           nsIFrame*        aParent,
98
 
                           nsIFrame*        aPrevInFlow)
99
 
{
100
 
  nsAutoString value, prefix;
101
 
 
102
 
  // Init our local attributes
103
 
 
104
 
  mChildCount = -1; // these will be updated in GetSelectedFrame()
105
 
  mSelection = 0;
106
 
  mSelectedFrame = nsnull;
107
 
  nsRefPtr<nsStyleContext> newStyleContext;
108
 
 
109
 
  mActionType = NS_MATHML_ACTION_TYPE_NONE;
110
 
  aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::actiontype_, value);
111
 
  if (!value.IsEmpty()) {
112
 
    if (value.EqualsLiteral("toggle"))
113
 
      mActionType = NS_MATHML_ACTION_TYPE_TOGGLE;
114
 
 
115
 
    // XXX use goto to jump out of these if?
116
 
 
117
 
    if (NS_MATHML_ACTION_TYPE_NONE == mActionType) {
118
 
      // expected tooltip prefix (8ch)...
119
 
      if (8 < value.Length() && 0 == value.Find("tooltip#"))
120
 
        mActionType = NS_MATHML_ACTION_TYPE_TOOLTIP;
121
 
    }
122
 
 
123
 
    if (NS_MATHML_ACTION_TYPE_NONE == mActionType) {
124
 
      // expected statusline prefix (11ch)...
125
 
      if (11 < value.Length() && 0 == value.Find("statusline#"))
126
 
        mActionType = NS_MATHML_ACTION_TYPE_STATUSLINE;
127
 
    }
128
 
 
129
 
    if (NS_MATHML_ACTION_TYPE_NONE == mActionType) {
130
 
      // expected restyle prefix (8ch)...
131
 
      if (8 < value.Length() && 0 == value.Find("restyle#")) {
132
 
        mActionType = NS_MATHML_ACTION_TYPE_RESTYLE;
133
 
        mRestyle = value;
134
 
 
135
 
        // Here is the situation:
136
 
        // When the attribute [actiontype="restyle#id"] is set, the Style System has
137
 
        // given us the associated style. But we want to start with our default style.
138
 
 
139
 
        // So... first, remove the attribute actiontype="restyle#id"
140
 
        // XXXbz this is pretty messed up, since this can change whether we
141
 
        // should have a frame at all.  This really needs a better solution.
142
 
        PRBool notify = PR_FALSE; // don't trigger a reflow yet!
143
 
        aContent->UnsetAttr(kNameSpaceID_None, nsGkAtoms::actiontype_, notify);
144
 
 
145
 
        // then, re-resolve our style
146
 
        nsStyleContext* parentStyleContext = GetStyleContext()->GetParent();
147
 
        newStyleContext = PresContext()->StyleSet()->
148
 
          ResolveStyleFor(aContent, parentStyleContext);
149
 
 
150
 
        if (!newStyleContext) 
151
 
          mRestyle.Truncate();
152
 
        else {
153
 
          if (newStyleContext != GetStyleContext())
154
 
            SetStyleContextWithoutNotification(newStyleContext);
155
 
          else
156
 
            mRestyle.Truncate();
157
 
        }
158
 
      }
159
 
    }
160
 
  }
161
 
 
162
 
  // Let the base class do the rest
163
 
  return nsMathMLContainerFrame::Init(aContent, aParent, aPrevInFlow);
164
 
}
165
 
 
166
 
nsresult
167
 
nsMathMLmactionFrame::ChildListChanged(PRInt32 aModType)
168
 
{
169
 
  // update cached values
170
 
  mChildCount = -1;
171
 
  mSelection = 0;
172
 
  mSelectedFrame = nsnull;
173
 
  GetSelectedFrame();
174
 
 
175
 
  return nsMathMLContainerFrame::ChildListChanged(aModType);
176
 
}
177
 
 
178
 
// return the frame whose number is given by the attribute selection="number"
179
 
nsIFrame* 
180
 
nsMathMLmactionFrame::GetSelectedFrame()
181
 
{
182
 
  nsAutoString value;
183
 
  PRInt32 selection; 
184
 
 
185
 
  mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::selection_, value);
186
 
  if (!value.IsEmpty()) {
187
 
    PRInt32 errorCode;
188
 
    selection = value.ToInteger(&errorCode);
189
 
    if (NS_FAILED(errorCode)) 
190
 
      selection = 1;
191
 
  }
192
 
  else selection = 1; // default is first frame
193
 
 
194
 
  if (-1 != mChildCount) { // we have been in this function before...
195
 
    // cater for invalid user-supplied selection
196
 
    if (selection > mChildCount || selection < 1) 
197
 
      selection = 1;
198
 
    // quick return if it is identical with our cache
199
 
    if (selection == mSelection) 
200
 
      return mSelectedFrame;
201
 
  }
202
 
 
203
 
  // get the selected child and cache new values...
204
 
  PRInt32 count = 0;
205
 
  nsIFrame* childFrame = mFrames.FirstChild();
206
 
  while (childFrame) {
207
 
    if (!mSelectedFrame) 
208
 
      mSelectedFrame = childFrame; // default is first child
209
 
    if (++count == selection) 
210
 
      mSelectedFrame = childFrame;
211
 
 
212
 
    childFrame = childFrame->GetNextSibling();
213
 
  }
214
 
  // cater for invalid user-supplied selection
215
 
  if (selection > count || selection < 1) 
216
 
    selection = 1;
217
 
 
218
 
  mChildCount = count;
219
 
  mSelection = selection;
220
 
 
221
 
  // if the selected child is an embellished operator,
222
 
  // we become embellished as well
223
 
  mPresentationData.baseFrame = mSelectedFrame;
224
 
  GetEmbellishDataFrom(mSelectedFrame, mEmbellishData);
225
 
 
226
 
  return mSelectedFrame;
227
 
}
228
 
 
229
 
NS_IMETHODIMP
230
 
nsMathMLmactionFrame::SetInitialChildList(nsIAtom*        aListName,
231
 
                                          nsIFrame*       aChildList)
232
 
{
233
 
  nsresult rv = nsMathMLContainerFrame::SetInitialChildList(aListName, aChildList);
234
 
 
235
 
  // This very first call to GetSelectedFrame() will cause us to be marked as an
236
 
  // embellished operator if the selected child is an embellished operator
237
 
  if (!GetSelectedFrame()) {
238
 
    mActionType = NS_MATHML_ACTION_TYPE_NONE;
239
 
  }
240
 
  else {
241
 
    // register us as a mouse event listener ...
242
 
    // printf("maction:%p registering as mouse event listener ...\n", this);
243
 
    mContent->AddEventListenerByIID(this, NS_GET_IID(nsIDOMMouseListener));
244
 
  }
245
 
  return rv;
246
 
}
247
 
 
248
 
//  Only paint the selected child...
249
 
NS_IMETHODIMP
250
 
nsMathMLmactionFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
251
 
                                       const nsRect&           aDirtyRect,
252
 
                                       const nsDisplayListSet& aLists)
253
 
{
254
 
  nsresult rv = DisplayBorderBackgroundOutline(aBuilder, aLists);
255
 
  NS_ENSURE_SUCCESS(rv, rv);
256
 
 
257
 
  nsIFrame* childFrame = GetSelectedFrame();
258
 
  if (childFrame) {
259
 
    // Put the child's background directly onto the content list
260
 
    nsDisplayListSet set(aLists, aLists.Content());
261
 
    // The children should be in content order
262
 
    rv = BuildDisplayListForChild(aBuilder, childFrame, aDirtyRect, set);
263
 
    NS_ENSURE_SUCCESS(rv, rv);
264
 
  }
265
 
 
266
 
#if defined(NS_DEBUG) && defined(SHOW_BOUNDING_BOX)
267
 
  // visual debug
268
 
  rv = DisplayBoundingMetrics(aBuilder, this, mReference, mBoundingMetrics, aLists);
269
 
#endif
270
 
  return rv;
271
 
}
272
 
 
273
 
// Only reflow the selected child ...
274
 
NS_IMETHODIMP
275
 
nsMathMLmactionFrame::Reflow(nsPresContext*          aPresContext,
276
 
                             nsHTMLReflowMetrics&     aDesiredSize,
277
 
                             const nsHTMLReflowState& aReflowState,
278
 
                             nsReflowStatus&          aStatus)
279
 
{
280
 
  nsresult rv = NS_OK;
281
 
  aStatus = NS_FRAME_COMPLETE;
282
 
  aDesiredSize.width = aDesiredSize.height = 0;
283
 
  aDesiredSize.ascent = 0;
284
 
  mBoundingMetrics.Clear();
285
 
  nsIFrame* childFrame = GetSelectedFrame();
286
 
  if (childFrame) {
287
 
    nsSize availSize(aReflowState.ComputedWidth(),
288
 
                     aReflowState.ComputedHeight());
289
 
    nsHTMLReflowState childReflowState(aPresContext, aReflowState,
290
 
                                       childFrame, availSize);
291
 
    rv = ReflowChild(childFrame, aPresContext, aDesiredSize,
292
 
                     childReflowState, aStatus);
293
 
    childFrame->SetRect(nsRect(0,aDesiredSize.ascent,
294
 
                        aDesiredSize.width,aDesiredSize.height));
295
 
    mBoundingMetrics = aDesiredSize.mBoundingMetrics;
296
 
  }
297
 
  FinalizeReflow(*aReflowState.rendContext, aDesiredSize);
298
 
  NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
299
 
  return rv;
300
 
}
301
 
 
302
 
// Only place the selected child ...
303
 
NS_IMETHODIMP
304
 
nsMathMLmactionFrame::Place(nsIRenderingContext& aRenderingContext,
305
 
                            PRBool               aPlaceOrigin,
306
 
                            nsHTMLReflowMetrics& aDesiredSize)
307
 
{
308
 
  aDesiredSize.width = aDesiredSize.height = 0;
309
 
  aDesiredSize.ascent = 0;
310
 
  mBoundingMetrics.Clear();
311
 
  nsIFrame* childFrame = GetSelectedFrame();
312
 
  if (childFrame) {
313
 
    GetReflowAndBoundingMetricsFor(childFrame, aDesiredSize, mBoundingMetrics);
314
 
    if (aPlaceOrigin) {
315
 
      FinishReflowChild(childFrame, PresContext(), nsnull, aDesiredSize, 0, 0, 0);
316
 
    }
317
 
    mReference.x = 0;
318
 
    mReference.y = aDesiredSize.ascent;
319
 
  }
320
 
  aDesiredSize.mBoundingMetrics = mBoundingMetrics;
321
 
  return NS_OK;
322
 
}
323
 
 
324
 
// ################################################################
325
 
// Event handlers 
326
 
// ################################################################
327
 
 
328
 
// helper to show a msg on the status bar
329
 
// curled from nsObjectFrame.cpp ...
330
 
nsresult
331
 
nsMathMLmactionFrame::ShowStatus(nsPresContext* aPresContext,
332
 
                                 nsString&       aStatusMsg)
333
 
{
334
 
  nsCOMPtr<nsISupports> cont = aPresContext->GetContainer();
335
 
  if (cont) {
336
 
    nsCOMPtr<nsIDocShellTreeItem> docShellItem(do_QueryInterface(cont));
337
 
    if (docShellItem) {
338
 
      nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
339
 
      docShellItem->GetTreeOwner(getter_AddRefs(treeOwner));
340
 
      if (treeOwner) {
341
 
        nsCOMPtr<nsIWebBrowserChrome> browserChrome(do_GetInterface(treeOwner));
342
 
        if (browserChrome) {
343
 
          browserChrome->SetStatus(nsIWebBrowserChrome::STATUS_LINK, aStatusMsg.get());
344
 
        }
345
 
      }
346
 
    }
347
 
  }
348
 
  return NS_OK;
349
 
}
350
 
 
351
 
NS_IMETHODIMP
352
 
nsMathMLmactionFrame::MouseOver(nsIDOMEvent* aMouseEvent) 
353
 
{
354
 
  // see if we should display a status message
355
 
  if (NS_MATHML_ACTION_TYPE_STATUSLINE == mActionType) {
356
 
    nsAutoString value;
357
 
    mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::actiontype_, value);
358
 
    // expected statusline prefix (11ch)...
359
 
    if (11 < value.Length() && 0 == value.Find("statusline#")) {
360
 
      value.Cut(0, 11);
361
 
      ShowStatus(PresContext(), value);
362
 
    }
363
 
  }
364
 
  return NS_OK;
365
 
}
366
 
 
367
 
NS_IMETHODIMP
368
 
nsMathMLmactionFrame::MouseOut(nsIDOMEvent* aMouseEvent) 
369
 
370
 
  // see if we should remove the status message
371
 
  if (NS_MATHML_ACTION_TYPE_STATUSLINE == mActionType) {
372
 
    nsAutoString value;
373
 
    value.SetLength(0);
374
 
    ShowStatus(PresContext(), value);
375
 
  }
376
 
  return NS_OK;
377
 
}
378
 
 
379
 
NS_IMETHODIMP
380
 
nsMathMLmactionFrame::MouseClick(nsIDOMEvent* aMouseEvent)
381
 
{
382
 
  if (NS_MATHML_ACTION_TYPE_TOGGLE == mActionType) {
383
 
    if (mChildCount > 1) {
384
 
      PRInt32 selection = (mSelection == mChildCount)? 1 : mSelection + 1;
385
 
      nsAutoString value;
386
 
      char cbuf[10];
387
 
      PR_snprintf(cbuf, sizeof(cbuf), "%d", selection);
388
 
      value.AssignASCII(cbuf);
389
 
      PRBool notify = PR_FALSE; // don't yet notify the document
390
 
      mContent->SetAttr(kNameSpaceID_None, nsGkAtoms::selection_, value, notify);
391
 
 
392
 
      // Now trigger a content-changed reflow...
393
 
      PresContext()->PresShell()->
394
 
        FrameNeedsReflow(mSelectedFrame, nsIPresShell::eTreeChange,
395
 
                         NS_FRAME_IS_DIRTY);
396
 
    }
397
 
  }
398
 
  else if (NS_MATHML_ACTION_TYPE_RESTYLE == mActionType) {
399
 
    if (!mRestyle.IsEmpty()) {
400
 
      nsCOMPtr<nsIDOMElement> node( do_QueryInterface(mContent) );
401
 
      if (node.get()) {
402
 
        if (nsContentUtils::HasNonEmptyAttr(mContent, kNameSpaceID_None,
403
 
                                            nsGkAtoms::actiontype_))
404
 
          node->RemoveAttribute(NS_LITERAL_STRING("actiontype"));
405
 
        else
406
 
          node->SetAttribute(NS_LITERAL_STRING("actiontype"), mRestyle);
407
 
 
408
 
        // Trigger a style change reflow
409
 
        PresContext()->PresShell()->
410
 
          FrameNeedsReflow(mSelectedFrame, nsIPresShell::eStyleChange,
411
 
                           NS_FRAME_IS_DIRTY);
412
 
      }
413
 
    }
414
 
  }
415
 
  return NS_OK;
416
 
}