~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/layout/xul/base/src/nsRootBoxFrame.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

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: NPL 1.1/GPL 2.0/LGPL 2.1
 
4
 *
 
5
 * The contents of this file are subject to the Netscape Public License
 
6
 * Version 1.1 (the "License"); you may not use this file except in
 
7
 * compliance with the License. You may obtain a copy of the License at
 
8
 * http://www.mozilla.org/NPL/
 
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.org code.
 
16
 *
 
17
 * The Initial Developer of the Original Code is 
 
18
 * Netscape Communications Corporation.
 
19
 * Portions created by the Initial Developer are Copyright (C) 1998
 
20
 * the Initial Developer. All Rights Reserved.
 
21
 *
 
22
 * Contributor(s):
 
23
 *
 
24
 * Alternatively, the contents of this file may be used under the terms of
 
25
 * either the GNU General Public License Version 2 or later (the "GPL"), or 
 
26
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
27
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
28
 * of those above. If you wish to allow use of your version of this file only
 
29
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
30
 * use your version of this file under the terms of the NPL, indicate your
 
31
 * decision by deleting the provisions above and replace them with the notice
 
32
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
33
 * the provisions above, a recipient may use your version of this file under
 
34
 * the terms of any one of the NPL, the GPL or the LGPL.
 
35
 *
 
36
 * ***** END LICENSE BLOCK ***** */
 
37
#include "nsHTMLParts.h"
 
38
#include "nsContainerFrame.h"
 
39
#include "nsCSSRendering.h"
 
40
#include "nsIDocument.h"
 
41
#include "nsIPresContext.h"
 
42
#include "nsViewsCID.h"
 
43
#include "nsIView.h"
 
44
#include "nsIViewManager.h"
 
45
#include "nsIWidget.h"
 
46
#include "nsPageFrame.h"
 
47
#include "nsIRenderingContext.h"
 
48
#include "nsGUIEvent.h"
 
49
#include "nsIDOMEvent.h"
 
50
#include "nsStyleConsts.h"
 
51
#include "nsIViewManager.h"
 
52
#include "nsHTMLAtoms.h"
 
53
#include "nsIEventStateManager.h"
 
54
#include "nsIDeviceContext.h"
 
55
#include "nsIScrollableView.h"
 
56
#include "nsLayoutAtoms.h"
 
57
#include "nsIPresShell.h"
 
58
#include "nsBoxFrame.h"
 
59
#include "nsStackLayout.h"
 
60
#include "nsIRootBox.h"
 
61
#include "nsIContent.h"
 
62
#include "nsXULTooltipListener.h"
 
63
 
 
64
// Interface IDs
 
65
 
 
66
//#define DEBUG_REFLOW
 
67
 
 
68
class nsRootBoxFrame : public nsBoxFrame, public nsIRootBox {
 
69
public:
 
70
 
 
71
  friend nsresult NS_NewBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame);
 
72
 
 
73
  nsRootBoxFrame(nsIPresShell* aShell);
 
74
 
 
75
  NS_DECL_ISUPPORTS_INHERITED
 
76
 
 
77
  NS_IMETHOD GetPopupSetFrame(nsIFrame** aResult);
 
78
  NS_IMETHOD SetPopupSetFrame(nsIFrame* aPopupSet);
 
79
  NS_IMETHOD GetDefaultTooltip(nsIContent** aResult);
 
80
  NS_IMETHOD SetDefaultTooltip(nsIContent* aTooltip);
 
81
  NS_IMETHOD AddTooltipSupport(nsIContent* aNode);
 
82
  NS_IMETHOD RemoveTooltipSupport(nsIContent* aNode);
 
83
 
 
84
  NS_IMETHOD AppendFrames(nsIPresContext* aPresContext,
 
85
                          nsIPresShell&   aPresShell,
 
86
                          nsIAtom*        aListName,
 
87
                          nsIFrame*       aFrameList);
 
88
  NS_IMETHOD InsertFrames(nsIPresContext* aPresContext,
 
89
                          nsIPresShell&   aPresShell,
 
90
                          nsIAtom*        aListName,
 
91
                          nsIFrame*       aPrevFrame,
 
92
                          nsIFrame*       aFrameList);
 
93
  NS_IMETHOD RemoveFrame(nsIPresContext* aPresContext,
 
94
                         nsIPresShell&   aPresShell,
 
95
                         nsIAtom*        aListName,
 
96
                         nsIFrame*       aOldFrame);
 
97
 
 
98
  NS_IMETHOD Reflow(nsIPresContext*          aPresContext,
 
99
                    nsHTMLReflowMetrics&     aDesiredSize,
 
100
                    const nsHTMLReflowState& aReflowState,
 
101
                    nsReflowStatus&          aStatus);
 
102
  NS_IMETHOD HandleEvent(nsIPresContext* aPresContext, 
 
103
                         nsGUIEvent*     aEvent,
 
104
                         nsEventStatus*  aEventStatus);
 
105
  NS_IMETHOD GetFrameForPoint(nsIPresContext* aPresContext,
 
106
                              const nsPoint& aPoint, 
 
107
                              nsFramePaintLayer aWhichLayer,
 
108
                              nsIFrame**     aFrame);
 
109
 
 
110
  /**
 
111
   * Get the "type" of the frame
 
112
   *
 
113
   * @see nsLayoutAtoms::rootFrame
 
114
   */
 
115
  virtual nsIAtom* GetType() const;
 
116
  
 
117
#ifdef DEBUG
 
118
  NS_IMETHOD GetFrameName(nsString& aResult) const;
 
119
#endif
 
120
 
 
121
  nsIFrame* mPopupSetFrame;
 
122
 
 
123
protected:
 
124
  nsIContent* mDefaultTooltip;
 
125
};
 
126
 
 
127
//----------------------------------------------------------------------
 
128
 
 
129
nsresult
 
130
NS_NewRootBoxFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
 
131
{
 
132
  NS_PRECONDITION(aNewFrame, "null OUT ptr");
 
133
  if (nsnull == aNewFrame) {
 
134
    return NS_ERROR_NULL_POINTER;
 
135
  }
 
136
  nsRootBoxFrame* it = new (aPresShell) nsRootBoxFrame (aPresShell);
 
137
  if (nsnull == it) {
 
138
    return NS_ERROR_OUT_OF_MEMORY;
 
139
  }
 
140
 
 
141
  *aNewFrame = it;
 
142
 
 
143
  return NS_OK;
 
144
}
 
145
 
 
146
nsRootBoxFrame::nsRootBoxFrame(nsIPresShell* aShell):nsBoxFrame(aShell, PR_TRUE)
 
147
{
 
148
  mPopupSetFrame = nsnull;
 
149
 
 
150
  nsCOMPtr<nsIBoxLayout> layout;
 
151
  NS_NewStackLayout(aShell, layout);
 
152
  SetLayoutManager(layout);
 
153
}
 
154
 
 
155
NS_IMETHODIMP
 
156
nsRootBoxFrame::AppendFrames(nsIPresContext* aPresContext,
 
157
                        nsIPresShell&   aPresShell,
 
158
                        nsIAtom*        aListName,
 
159
                        nsIFrame*       aFrameList)
 
160
{
 
161
  nsresult  rv;
 
162
 
 
163
  NS_ASSERTION(!aListName, "unexpected child list name");
 
164
  NS_PRECONDITION(mFrames.IsEmpty(), "already have a child frame");
 
165
  if (aListName) {
 
166
    // We only support unnamed principal child list
 
167
    rv = NS_ERROR_INVALID_ARG;
 
168
 
 
169
  } else if (!mFrames.IsEmpty()) {
 
170
    // We only allow a single child frame
 
171
    rv = NS_ERROR_FAILURE;
 
172
 
 
173
  } else {
 
174
    rv = nsBoxFrame::AppendFrames(aPresContext, aPresShell, aListName, aFrameList);
 
175
  }
 
176
 
 
177
  return rv;
 
178
}
 
179
 
 
180
NS_IMETHODIMP
 
181
nsRootBoxFrame::InsertFrames(nsIPresContext* aPresContext,
 
182
                        nsIPresShell&   aPresShell,
 
183
                        nsIAtom*        aListName,
 
184
                        nsIFrame*       aPrevFrame,
 
185
                        nsIFrame*       aFrameList)
 
186
{
 
187
  nsresult  rv;
 
188
 
 
189
  // Because we only support a single child frame inserting is the same
 
190
  // as appending
 
191
  NS_PRECONDITION(!aPrevFrame, "unexpected previous sibling frame");
 
192
  if (aPrevFrame) {
 
193
    rv = NS_ERROR_UNEXPECTED;
 
194
  } else {
 
195
    rv = AppendFrames(aPresContext, aPresShell, aListName, aFrameList);
 
196
  }
 
197
 
 
198
  return rv;
 
199
}
 
200
 
 
201
NS_IMETHODIMP
 
202
nsRootBoxFrame::RemoveFrame(nsIPresContext* aPresContext,
 
203
                       nsIPresShell&   aPresShell,
 
204
                       nsIAtom*        aListName,
 
205
                       nsIFrame*       aOldFrame)
 
206
{
 
207
  nsresult  rv;
 
208
 
 
209
  NS_ASSERTION(!aListName, "unexpected child list name");
 
210
  if (aListName) {
 
211
    // We only support the unnamed principal child list
 
212
    rv = NS_ERROR_INVALID_ARG;
 
213
  
 
214
  } else if (aOldFrame == mFrames.FirstChild()) {
 
215
     rv = nsBoxFrame::RemoveFrame(aPresContext, aPresShell, aListName, aOldFrame);
 
216
  } else {
 
217
    rv = NS_ERROR_FAILURE;
 
218
  }
 
219
 
 
220
  return rv;
 
221
}
 
222
 
 
223
#ifdef DEBUG_REFLOW
 
224
PRInt32 gReflows = 0;
 
225
#endif
 
226
 
 
227
NS_IMETHODIMP
 
228
nsRootBoxFrame::Reflow(nsIPresContext*          aPresContext,
 
229
                       nsHTMLReflowMetrics&     aDesiredSize,
 
230
                       const nsHTMLReflowState& aReflowState,
 
231
                       nsReflowStatus&          aStatus)
 
232
{
 
233
  DO_GLOBAL_REFLOW_COUNT("nsRootBoxFrame", aReflowState.reason);
 
234
 
 
235
#ifdef DEBUG_REFLOW
 
236
  gReflows++;
 
237
  printf("----Reflow %d----\n", gReflows);
 
238
#endif
 
239
  return nsBoxFrame::Reflow(aPresContext, aDesiredSize, aReflowState, aStatus);
 
240
}
 
241
 
 
242
NS_IMETHODIMP
 
243
nsRootBoxFrame::HandleEvent(nsIPresContext* aPresContext, 
 
244
                       nsGUIEvent* aEvent,
 
245
                       nsEventStatus* aEventStatus)
 
246
{
 
247
  NS_ENSURE_ARG_POINTER(aEventStatus);
 
248
  if (nsEventStatus_eConsumeNoDefault == *aEventStatus) {
 
249
    return NS_OK;
 
250
  }
 
251
 
 
252
  if (aEvent->message == NS_MOUSE_LEFT_BUTTON_UP ||
 
253
      aEvent->message == NS_MOUSE_MIDDLE_BUTTON_UP ||
 
254
      aEvent->message == NS_MOUSE_RIGHT_BUTTON_UP) {
 
255
    nsFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
 
256
  }
 
257
 
 
258
  return NS_OK;
 
259
}
 
260
 
 
261
NS_IMETHODIMP
 
262
nsRootBoxFrame::GetFrameForPoint(nsIPresContext* aPresContext,
 
263
                                   const nsPoint& aPoint, 
 
264
                                   nsFramePaintLayer aWhichLayer,
 
265
                                   nsIFrame**     aFrame)
 
266
{
 
267
  // this should act like a block, so we need to override
 
268
  return nsBoxFrame::GetFrameForPoint(aPresContext, aPoint, aWhichLayer, aFrame);
 
269
}
 
270
 
 
271
nsIAtom*
 
272
nsRootBoxFrame::GetType() const
 
273
{
 
274
  return nsLayoutAtoms::rootFrame;
 
275
}
 
276
 
 
277
NS_IMETHODIMP
 
278
nsRootBoxFrame::GetPopupSetFrame(nsIFrame** aResult)
 
279
{
 
280
  *aResult = mPopupSetFrame;
 
281
  return NS_OK;
 
282
}
 
283
 
 
284
NS_IMETHODIMP
 
285
nsRootBoxFrame::SetPopupSetFrame(nsIFrame* aPopupSet)
 
286
{
 
287
  // Under normal conditions this should only be called once.  However,
 
288
  // if something triggers ReconstructDocElementHierarchy, we will
 
289
  // destroy this frame's child (the nsDocElementBoxFrame), but not this
 
290
  // frame.  This will cause the popupset to remove itself by calling
 
291
  // |SetPopupSetFrame(nsnull)|, and then we'll be able to accept a new
 
292
  // popupset.  Since the anonymous content is associated with the
 
293
  // nsDocElementBoxFrame, we'll get a new popupset when the new doc
 
294
  // element box frame is created.
 
295
  if (!mPopupSetFrame || !aPopupSet) {
 
296
    mPopupSetFrame = aPopupSet;
 
297
  } else {
 
298
    NS_NOTREACHED("Popup set is already defined! Only 1 allowed.");
 
299
  }
 
300
  return NS_OK;
 
301
}
 
302
 
 
303
NS_IMETHODIMP
 
304
nsRootBoxFrame::GetDefaultTooltip(nsIContent** aTooltip)
 
305
{
 
306
  *aTooltip = mDefaultTooltip;
 
307
  return NS_OK;
 
308
}
 
309
 
 
310
NS_IMETHODIMP
 
311
nsRootBoxFrame::SetDefaultTooltip(nsIContent* aTooltip)
 
312
{
 
313
  mDefaultTooltip = aTooltip;
 
314
  return NS_OK;
 
315
}
 
316
 
 
317
NS_IMETHODIMP
 
318
nsRootBoxFrame::AddTooltipSupport(nsIContent* aNode)
 
319
{
 
320
  // listener will be refcounted by dom event targets that
 
321
  // it will add itself to, and destroyed when those targets
 
322
  // are destroyed
 
323
  nsXULTooltipListener* listener = new nsXULTooltipListener();
 
324
  if (!listener)
 
325
    return NS_ERROR_OUT_OF_MEMORY;
 
326
 
 
327
  listener->Init(aNode, this);
 
328
  return NS_OK;
 
329
}
 
330
 
 
331
NS_IMETHODIMP
 
332
nsRootBoxFrame::RemoveTooltipSupport(nsIContent* aNode)
 
333
{
 
334
  // XXjh yuck, I'll have to implement a way to get at
 
335
  // the tooltip listener for a given node to make 
 
336
  // this work.  Not crucial, we aren't removing 
 
337
  // tooltips from any nodes in the app just yet.
 
338
  return NS_ERROR_NOT_IMPLEMENTED;
 
339
}
 
340
 
 
341
NS_IMETHODIMP_(nsrefcnt) 
 
342
nsRootBoxFrame::AddRef(void)
 
343
{
 
344
  return NS_OK;
 
345
}
 
346
 
 
347
NS_IMETHODIMP_(nsrefcnt)
 
348
nsRootBoxFrame::Release(void)
 
349
{
 
350
  return NS_OK;
 
351
}
 
352
 
 
353
NS_INTERFACE_MAP_BEGIN(nsRootBoxFrame)
 
354
  NS_INTERFACE_MAP_ENTRY(nsIRootBox)
 
355
NS_INTERFACE_MAP_END_INHERITING(nsBoxFrame)
 
356
 
 
357
#ifdef DEBUG
 
358
NS_IMETHODIMP
 
359
nsRootBoxFrame::GetFrameName(nsString& aResult) const
 
360
{
 
361
  return MakeFrameName(NS_LITERAL_STRING("RootBox"), aResult);
 
362
}
 
363
#endif