forked from rnewman/services-central-old
-
Notifications
You must be signed in to change notification settings - Fork 0
/
nsIFrame.h
2515 lines (2231 loc) · 99.7 KB
/
nsIFrame.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 sw=2 et tw=78: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/I
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* interface for all rendering objects */
#ifndef nsIFrame_h___
#define nsIFrame_h___
/* nsIFrame is in the process of being deCOMtaminated, i.e., this file is eventually
going to be eliminated, and all callers will use nsFrame instead. At the moment
we're midway through this process, so you will see inlined functions and member
variables in this file. -dwh */
#include <stdio.h>
#include "nsQueryFrame.h"
#include "nsEvent.h"
#include "nsStyleStruct.h"
#include "nsStyleContext.h"
#include "nsIContent.h"
#include "nsHTMLReflowMetrics.h"
#include "gfxMatrix.h"
/**
* New rules of reflow:
* 1. you get a WillReflow() followed by a Reflow() followed by a DidReflow() in order
* (no separate pass over the tree)
* 2. it's the parent frame's responsibility to size/position the child's view (not
* the child frame's responsibility as it is today) during reflow (and before
* sending the DidReflow() notification)
* 3. positioning of child frames (and their views) is done on the way down the tree,
* and sizing of child frames (and their views) on the way back up
* 4. if you move a frame (outside of the reflow process, or after reflowing it),
* then you must make sure that its view (or its child frame's views) are re-positioned
* as well. It's reasonable to not position the view until after all reflowing the
* entire line, for example, but the frame should still be positioned and sized (and
* the view sized) during the reflow (i.e., before sending the DidReflow() notification)
* 5. the view system handles moving of widgets, i.e., it's not our problem
*/
struct nsHTMLReflowState;
class nsHTMLReflowCommand;
class nsIAtom;
class nsPresContext;
class nsIPresShell;
class nsIRenderingContext;
class nsIView;
class nsIWidget;
class nsIDOMRange;
class nsISelectionController;
class nsBoxLayoutState;
class nsIBoxLayout;
class nsILineIterator;
#ifdef ACCESSIBILITY
class nsIAccessible;
#endif
class nsDisplayListBuilder;
class nsDisplayListSet;
class nsDisplayList;
class gfxSkipChars;
class gfxSkipCharsIterator;
class gfxContext;
class nsLineList_iterator;
struct nsPeekOffsetStruct;
struct nsPoint;
struct nsRect;
struct nsSize;
struct nsMargin;
typedef class nsIFrame nsIBox;
// IID for the nsIFrame interface
// 7b437d20-a34e-11dd-ad8b-0800200c9a66
#define NS_IFRAME_IID \
{ 0x7b437d20, 0xa34e, 0x11dd, \
{ 0xad, 0x8b, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } }
/**
* Indication of how the frame can be split. This is used when doing runaround
* of floats, and when pulling up child frames from a next-in-flow.
*
* The choices are splittable, not splittable at all, and splittable in
* a non-rectangular fashion. This last type only applies to block-level
* elements, and indicates whether splitting can be used when doing runaround.
* If you can split across page boundaries, but you expect each continuing
* frame to be the same width then return frSplittable and not
* frSplittableNonRectangular.
*
* @see #GetSplittableType()
*/
typedef PRUint32 nsSplittableType;
#define NS_FRAME_NOT_SPLITTABLE 0 // Note: not a bit!
#define NS_FRAME_SPLITTABLE 0x1
#define NS_FRAME_SPLITTABLE_NON_RECTANGULAR 0x3
#define NS_FRAME_IS_SPLITTABLE(type)\
(0 != ((type) & NS_FRAME_SPLITTABLE))
#define NS_FRAME_IS_NOT_SPLITTABLE(type)\
(0 == ((type) & NS_FRAME_SPLITTABLE))
#define NS_INTRINSIC_WIDTH_UNKNOWN nscoord_MIN
//----------------------------------------------------------------------
/**
* Frame state bits. Any bits not listed here are reserved for future
* extensions, but must be stored by the frames.
*/
typedef PRUint32 nsFrameState;
enum {
NS_FRAME_IN_REFLOW = 0x00000001,
// This is only set during painting
NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO = 0x00000001,
// This bit is set when a frame is created. After it has been reflowed
// once (during the DidReflow with a finished state) the bit is
// cleared.
NS_FRAME_FIRST_REFLOW = 0x00000002,
// For a continuation frame, if this bit is set, then this a "fluid"
// continuation, i.e., across a line boundary. Otherwise it's a "hard"
// continuation, e.g. a bidi continuation.
NS_FRAME_IS_FLUID_CONTINUATION = 0x00000004,
/*
* This bit is obsolete, replaced by HasOverflowRect().
* The definition is left here as a placeholder for now, to remind us
* that this bit is now free to allocate for other purposes.
* // This bit is set when the frame's overflow rect is
* // different from its border rect (i.e. GetOverflowRect() != GetRect())
* NS_FRAME_OUTSIDE_CHILDREN = 0x00000008,
*/
// If this bit is set, then a reference to the frame is being held
// elsewhere. The frame may want to send a notification when it is
// destroyed to allow these references to be cleared.
NS_FRAME_EXTERNAL_REFERENCE = 0x00000010,
// If this bit is set, this frame or one of its descendants has a
// percentage height that depends on an ancestor of this frame.
// (Or it did at one point in the past, since we don't necessarily clear
// the bit when it's no longer needed; it's an optimization.)
NS_FRAME_CONTAINS_RELATIVE_HEIGHT = 0x00000020,
// If this bit is set, then the frame corresponds to generated content
// Such frames store an nsCOMArray<nsIContent> of their generated content
// in the nsGkAtoms::generatedContent frame property, except for continuation
// frames.
NS_FRAME_GENERATED_CONTENT = 0x00000040,
// If this bit is set the frame is a continuation that is holding overflow,
// i.e. it is a next-in-flow created to hold overflow after the box's
// height has ended. This means the frame should be a) at the top of the
// page and b) invisible: no borders, zero height, ignored in margin
// collapsing, etc. See nsContainerFrame.h
NS_FRAME_IS_OVERFLOW_CONTAINER = 0x00000080,
// If this bit is set, then the frame has been moved out of the flow,
// e.g., it is absolutely positioned or floated
NS_FRAME_OUT_OF_FLOW = 0x00000100,
// If this bit is set, then the frame reflects content that may be selected
NS_FRAME_SELECTED_CONTENT = 0x00000200,
// If this bit is set, then the frame is dirty and needs to be reflowed.
// This bit is set when the frame is first created.
// This bit is cleared by DidReflow after the required call to Reflow has
// finished.
// Do not set this bit yourself if you plan to pass the frame to
// nsIPresShell::FrameNeedsReflow. Pass the right arguments instead.
NS_FRAME_IS_DIRTY = 0x00000400,
// If this bit is set then the frame is too deep in the frame tree, and
// we'll stop updating it and its children, to prevent stack overflow
// and the like.
NS_FRAME_TOO_DEEP_IN_FRAME_TREE = 0x00000800,
// If this bit is set, either:
// 1. the frame has children that have either NS_FRAME_IS_DIRTY or
// NS_FRAME_HAS_DIRTY_CHILDREN, or
// 2. the frame has had descendants removed.
// It means that Reflow needs to be called, but that Reflow will not
// do as much work as it would if NS_FRAME_IS_DIRTY were set.
// This bit is cleared by DidReflow after the required call to Reflow has
// finished.
// Do not set this bit yourself if you plan to pass the frame to
// nsIPresShell::FrameNeedsReflow. Pass the right arguments instead.
NS_FRAME_HAS_DIRTY_CHILDREN = 0x00001000,
// If this bit is set, the frame has an associated view
NS_FRAME_HAS_VIEW = 0x00002000,
// If this bit is set, the frame was created from anonymous content.
NS_FRAME_INDEPENDENT_SELECTION = 0x00004000,
// If this bit is set, the frame is "special" (lame term, I know),
// which means that it is part of the mangled frame hierarchy that
// results when an inline has been split because of a nested block.
NS_FRAME_IS_SPECIAL = 0x00008000,
// If this bit is set, the frame may have a transform that it applies
// to its coordinate system (e.g. CSS transform, SVG foreignObject).
// This is used primarily in GetTransformMatrix to optimize for the
// common case.
// ALSO, if this bit is set, the frame's first-continuation may
// have an associated nsSVGRenderingObserverList.
NS_FRAME_MAY_BE_TRANSFORMED_OR_HAVE_RENDERING_OBSERVERS = 0x00010000,
#ifdef IBMBIDI
// If this bit is set, the frame itself is a bidi continuation,
// or is incomplete (its next sibling is a bidi continuation)
NS_FRAME_IS_BIDI = 0x00020000,
#endif
// If this bit is set the frame has descendant with a view
NS_FRAME_HAS_CHILD_WITH_VIEW = 0x00040000,
// If this bit is set, then reflow may be dispatched from the current
// frame instead of the root frame.
NS_FRAME_REFLOW_ROOT = 0x00080000,
// The lower 20 bits of the frame state word are reserved by this API.
NS_FRAME_RESERVED = 0x000FFFFF,
// The upper 12 bits of the frame state word are reserved for frame
// implementations.
NS_FRAME_IMPL_RESERVED = 0xFFF00000,
// Box layout bits
NS_STATE_IS_HORIZONTAL = 0x00400000,
NS_STATE_IS_DIRECTION_NORMAL = 0x80000000
};
// Helper macros
#define NS_SUBTREE_DIRTY(_frame) \
(((_frame)->GetStateBits() & \
(NS_FRAME_IS_DIRTY | NS_FRAME_HAS_DIRTY_CHILDREN)) != 0)
//----------------------------------------------------------------------
enum nsSelectionAmount {
eSelectCharacter = 0,
eSelectWord = 1,
eSelectLine = 2, //previous drawn line in flow.
eSelectBeginLine = 3,
eSelectEndLine = 4,
eSelectNoAmount = 5, //just bounce back current offset.
eSelectParagraph = 6 //select a "paragraph"
};
enum nsDirection {
eDirNext = 0,
eDirPrevious= 1
};
enum nsSpread {
eSpreadNone = 0,
eSpreadAcross = 1,
eSpreadDown = 2
};
// Carried out margin flags
#define NS_CARRIED_TOP_MARGIN_IS_AUTO 0x1
#define NS_CARRIED_BOTTOM_MARGIN_IS_AUTO 0x2
//----------------------------------------------------------------------
/**
* Reflow status returned by the reflow methods. There are three
* completion statuses, represented by two bit flags.
*
* NS_FRAME_COMPLETE means the frame is fully complete.
*
* NS_FRAME_NOT_COMPLETE bit flag means the frame does not map all its
* content, and that the parent frame should create a continuing frame.
* If this bit isn't set it means the frame does map all its content.
* This bit is mutually exclusive with NS_FRAME_OVERFLOW_INCOMPLETE.
*
* NS_FRAME_OVERFLOW_INCOMPLETE bit flag means that the frame has
* overflow that is not complete, but its own box is complete.
* (This happens when content overflows a fixed-height box.)
* The reflower should place and size the frame and continue its reflow,
* but needs to create an overflow container as a continuation for this
* frame. See nsContainerFrame.h for more information.
* This bit is mutually exclusive with NS_FRAME_NOT_COMPLETE.
*
* Please use the SET macro for handling
* NS_FRAME_NOT_COMPLETE and NS_FRAME_OVERFLOW_INCOMPLETE.
*
* NS_FRAME_REFLOW_NEXTINFLOW bit flag means that the next-in-flow is
* dirty, and also needs to be reflowed. This status only makes sense
* for a frame that is not complete, i.e. you wouldn't set both
* NS_FRAME_COMPLETE and NS_FRAME_REFLOW_NEXTINFLOW.
*
* The low 8 bits of the nsReflowStatus are reserved for future extensions;
* the remaining 24 bits are zero (and available for extensions; however
* API's that accept/return nsReflowStatus must not receive/return any
* extension bits).
*
* @see #Reflow()
*/
typedef PRUint32 nsReflowStatus;
#define NS_FRAME_COMPLETE 0 // Note: not a bit!
#define NS_FRAME_NOT_COMPLETE 0x1
#define NS_FRAME_REFLOW_NEXTINFLOW 0x2
#define NS_FRAME_OVERFLOW_INCOMPLETE 0x4
#define NS_FRAME_IS_COMPLETE(status) \
(0 == ((status) & NS_FRAME_NOT_COMPLETE))
#define NS_FRAME_IS_NOT_COMPLETE(status) \
(0 != ((status) & NS_FRAME_NOT_COMPLETE))
#define NS_FRAME_OVERFLOW_IS_INCOMPLETE(status) \
(0 != ((status) & NS_FRAME_OVERFLOW_INCOMPLETE))
#define NS_FRAME_IS_FULLY_COMPLETE(status) \
(NS_FRAME_IS_COMPLETE(status) && !NS_FRAME_OVERFLOW_IS_INCOMPLETE(status))
// These macros set or switch incompete statuses without touching th
// NS_FRAME_REFLOW_NEXTINFLOW bit.
#define NS_FRAME_SET_INCOMPLETE(status) \
status = (status & ~NS_FRAME_OVERFLOW_INCOMPLETE) | NS_FRAME_NOT_COMPLETE
#define NS_FRAME_SET_OVERFLOW_INCOMPLETE(status) \
status = (status & ~NS_FRAME_NOT_COMPLETE) | NS_FRAME_OVERFLOW_INCOMPLETE
// This macro tests to see if an nsReflowStatus is an error value
// or just a regular return value
#define NS_IS_REFLOW_ERROR(_status) (PRInt32(_status) < 0)
/**
* Extensions to the reflow status bits defined by nsIFrameReflow
*/
// This bit is set, when a break is requested. This bit is orthogonal
// to the nsIFrame::nsReflowStatus completion bits.
#define NS_INLINE_BREAK 0x0100
// When a break is requested, this bit when set indicates that the
// break should occur after the frame just reflowed; when the bit is
// clear the break should occur before the frame just reflowed.
#define NS_INLINE_BREAK_BEFORE 0x0000
#define NS_INLINE_BREAK_AFTER 0x0200
// The type of break requested can be found in these bits.
#define NS_INLINE_BREAK_TYPE_MASK 0xF000
// Set when a break was induced by completion of a first-letter
#define NS_INLINE_BREAK_FIRST_LETTER_COMPLETE 0x10000
//----------------------------------------
// Macros that use those bits
#define NS_INLINE_IS_BREAK(_status) \
(0 != ((_status) & NS_INLINE_BREAK))
#define NS_INLINE_IS_BREAK_AFTER(_status) \
(0 != ((_status) & NS_INLINE_BREAK_AFTER))
#define NS_INLINE_IS_BREAK_BEFORE(_status) \
(NS_INLINE_BREAK == ((_status) & (NS_INLINE_BREAK|NS_INLINE_BREAK_AFTER)))
#define NS_INLINE_GET_BREAK_TYPE(_status) (((_status) >> 12) & 0xF)
#define NS_INLINE_MAKE_BREAK_TYPE(_type) ((_type) << 12)
// Construct a line-break-before status. Note that there is no
// completion status for a line-break before because we *know* that
// the frame will be reflowed later and hence it's current completion
// status doesn't matter.
#define NS_INLINE_LINE_BREAK_BEFORE() \
(NS_INLINE_BREAK | NS_INLINE_BREAK_BEFORE | \
NS_INLINE_MAKE_BREAK_TYPE(NS_STYLE_CLEAR_LINE))
// Take a completion status and add to it the desire to have a
// line-break after. For this macro we do need the completion status
// because the user of the status will need to know whether to
// continue the frame or not.
#define NS_INLINE_LINE_BREAK_AFTER(_completionStatus) \
((_completionStatus) | NS_INLINE_BREAK | NS_INLINE_BREAK_AFTER | \
NS_INLINE_MAKE_BREAK_TYPE(NS_STYLE_CLEAR_LINE))
// The frame (not counting a continuation) did not fit in the available height and
// wasn't at the top of a page. If it was at the top of a page, then it is not
// possible to reflow it again with more height, so we don't set it in that case.
#define NS_FRAME_TRUNCATED 0x0010
#define NS_FRAME_IS_TRUNCATED(status) \
(0 != ((status) & NS_FRAME_TRUNCATED))
#define NS_FRAME_SET_TRUNCATION(status, aReflowState, aMetrics) \
aReflowState.SetTruncated(aMetrics, &status);
// Merge the incompleteness, truncation and NS_FRAME_REFLOW_NEXTINFLOW
// status from aSecondary into aPrimary.
void NS_MergeReflowStatusInto(nsReflowStatus* aPrimary,
nsReflowStatus aSecondary);
//----------------------------------------------------------------------
/**
* DidReflow status values.
*/
typedef PRBool nsDidReflowStatus;
#define NS_FRAME_REFLOW_NOT_FINISHED PR_FALSE
#define NS_FRAME_REFLOW_FINISHED PR_TRUE
/**
* The overflow rect may be stored as four 1-byte deltas each strictly
* LESS THAN 0xff, for the four edges of the rectangle, or the four bytes
* may be read as a single 32-bit "overflow-rect type" value including
* at least one 0xff byte as an indicator that the value does NOT
* represent four deltas.
* If all four deltas are zero, this means that no overflow rect has
* actually been set (this is the initial state of newly-created frames).
*/
#define NS_FRAME_OVERFLOW_DELTA_MAX 0xfe // max delta we can store
#define NS_FRAME_OVERFLOW_NONE 0x00000000 // there is no overflow rect;
// code relies on this being
// the all-zero value
#define NS_FRAME_OVERFLOW_LARGE 0x000000ff // overflow is stored as a
// separate rect property
//----------------------------------------------------------------------
/**
* A frame in the layout model. This interface is supported by all frame
* objects.
*
* Frames can have multiple child lists: the default unnamed child list
* (referred to as the <i>principal</i> child list, and additional named
* child lists. There is an ordering of frames within a child list, but
* there is no order defined between frames in different child lists of
* the same parent frame.
*
* Frames are NOT reference counted. Use the Destroy() member function
* to destroy a frame. The lifetime of the frame hierarchy is bounded by the
* lifetime of the presentation shell which owns the frames.
*
* nsIFrame is a private Gecko interface. If you are not Gecko then you
* should not use it. If you're not in layout, then you won't be able to
* link to many of the functions defined here. Too bad.
*
* If you're not in layout but you must call functions in here, at least
* restrict yourself to calling virtual methods, which won't hurt you as badly.
*/
class nsIFrame : public nsQueryFrame
{
public:
NS_DECLARE_FRAME_ACCESSOR(nsIFrame)
nsPresContext* PresContext() const {
return GetStyleContext()->GetRuleNode()->GetPresContext();
}
/**
* Called to initialize the frame. This is called immediately after creating
* the frame.
*
* If the frame is a continuing frame, then aPrevInFlow indicates the previous
* frame (the frame that was split).
*
* If you want a view associated with your frame, you should create the view
* now.
*
* @param aContent the content object associated with the frame
* @param aGeometricParent the geometric parent frame
* @param aContentParent the content parent frame
* @param aContext the style context associated with the frame
* @param aPrevInFlow the prev-in-flow frame
*/
NS_IMETHOD Init(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* aPrevInFlow) = 0;
/**
* Destroys this frame and each of its child frames (recursively calls
* Destroy() for each child)
*/
virtual void Destroy() = 0;
/*
* Notify the frame that it has been removed as the primary frame for its content
*/
virtual void RemovedAsPrimaryFrame() {}
/**
* Called to set the initial list of frames. This happens after the frame
* has been initialized.
*
* This is only called once for a given child list, and won't be called
* at all for child lists with no initial list of frames.
*
* @param aListName the name of the child list. A NULL pointer for the atom
* name means the unnamed principal child list
* @param aChildList list of child frames. Each of the frames has its
* NS_FRAME_IS_DIRTY bit set
* @return NS_ERROR_INVALID_ARG if there is no child list with the specified
* name,
* NS_ERROR_UNEXPECTED if the frame is an atomic frame or if the
* initial list of frames has already been set for that child list,
* NS_OK otherwise
* @see #Init()
*/
NS_IMETHOD SetInitialChildList(nsIAtom* aListName,
nsIFrame* aChildList) = 0;
/**
* This method is responsible for appending frames to the frame
* list. The implementation should append the frames to the specified
* child list and then generate a reflow command.
*
* @param aListName the name of the child list. A NULL pointer for the atom
* name means the unnamed principal child list
* @param aFrameList list of child frames to append. Each of the frames has
* its NS_FRAME_IS_DIRTY bit set
* @return NS_ERROR_INVALID_ARG if there is no child list with the specified
* name,
* NS_ERROR_UNEXPECTED if the frame is an atomic frame,
* NS_OK otherwise
*/
NS_IMETHOD AppendFrames(nsIAtom* aListName,
nsIFrame* aFrameList) = 0;
/**
* This method is responsible for inserting frames into the frame
* list. The implementation should insert the new frames into the specified
* child list and then generate a reflow command.
*
* @param aListName the name of the child list. A NULL pointer for the atom
* name means the unnamed principal child list
* @param aPrevFrame the frame to insert frames <b>after</b>
* @param aFrameList list of child frames to insert <b>after</b> aPrevFrame.
* Each of the frames has its NS_FRAME_IS_DIRTY bit set
* @return NS_ERROR_INVALID_ARG if there is no child list with the specified
* name,
* NS_ERROR_UNEXPECTED if the frame is an atomic frame,
* NS_OK otherwise
*/
NS_IMETHOD InsertFrames(nsIAtom* aListName,
nsIFrame* aPrevFrame,
nsIFrame* aFrameList) = 0;
/**
* This method is responsible for removing a frame in the frame
* list. The implementation should do something with the removed frame
* and then generate a reflow command. The implementation is responsible
* for destroying aOldFrame (the caller mustn't destroy aOldFrame).
*
* @param aListName the name of the child list. A NULL pointer for the atom
* name means the unnamed principal child list
* @param aOldFrame the frame to remove
* @return NS_ERROR_INVALID_ARG if there is no child list with the specified
* name,
* NS_ERROR_FAILURE if the child frame is not in the specified
* child list,
* NS_ERROR_UNEXPECTED if the frame is an atomic frame,
* NS_OK otherwise
*/
NS_IMETHOD RemoveFrame(nsIAtom* aListName,
nsIFrame* aOldFrame) = 0;
/**
* Get the content object associated with this frame. Does not add a reference.
*/
nsIContent* GetContent() const { return mContent; }
/**
* Get the frame that should be the parent for the frames of child elements
* May return nsnull during reflow
*/
virtual nsIFrame* GetContentInsertionFrame() { return this; }
/**
* Get the offsets of the frame. most will be 0,0
*
*/
NS_IMETHOD GetOffsets(PRInt32 &start, PRInt32 &end) const = 0;
/**
* Reset the offsets when splitting frames during Bidi reordering
*
*/
virtual void AdjustOffsetsForBidi(PRInt32 aStart, PRInt32 aEnd) {}
/**
* Get the style context associated with this frame.
*
*/
nsStyleContext* GetStyleContext() const { return mStyleContext; }
void SetStyleContext(nsStyleContext* aContext)
{
if (aContext != mStyleContext) {
nsStyleContext* oldStyleContext = mStyleContext;
mStyleContext = aContext;
if (aContext) {
aContext->AddRef();
DidSetStyleContext(oldStyleContext);
}
if (oldStyleContext)
oldStyleContext->Release();
}
}
void SetStyleContextWithoutNotification(nsStyleContext* aContext)
{
if (aContext != mStyleContext) {
if (mStyleContext)
mStyleContext->Release();
mStyleContext = aContext;
if (aContext) {
aContext->AddRef();
}
}
}
// Style post processing hook
// Attention: the old style context is the one we're forgetting,
// and hence possibly completely bogus for GetStyle* purposes.
// Use PeekStyleData instead.
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext) = 0;
/**
* Get the style data associated with this frame. This returns a
* const style struct pointer that should never be modified. See
* |nsIStyleContext::GetStyleData| for more information.
*
* The use of the typesafe functions below is preferred to direct use
* of this function.
*/
virtual const void* GetStyleDataExternal(nsStyleStructID aSID) const = 0;
/**
* Define typesafe getter functions for each style struct by
* preprocessing the list of style structs. These functions are the
* preferred way to get style data. The macro creates functions like:
* const nsStyleBorder* GetStyleBorder();
* const nsStyleColor* GetStyleColor();
*/
#ifdef _IMPL_NS_LAYOUT
#define STYLE_STRUCT(name_, checkdata_cb_, ctor_args_) \
const nsStyle##name_ * GetStyle##name_ () const { \
NS_ASSERTION(mStyleContext, "No style context found!"); \
return mStyleContext->GetStyle##name_ (); \
}
#else
#define STYLE_STRUCT(name_, checkdata_cb_, ctor_args_) \
const nsStyle##name_ * GetStyle##name_ () const { \
return static_cast<const nsStyle##name_*>( \
GetStyleDataExternal(eStyleStruct_##name_)); \
}
#endif
#include "nsStyleStructList.h"
#undef STYLE_STRUCT
/**
* These methods are to access any additional style contexts that
* the frame may be holding. These are contexts that are children
* of the frame's primary context and are NOT used as style contexts
* for any child frames. These contexts also MUST NOT have any child
* contexts whatsoever. If you need to insert style contexts into the
* style tree, then you should create pseudo element frames to own them
* The indicies must be consecutive and implementations MUST return an
* NS_ERROR_INVALID_ARG if asked for an index that is out of range.
*/
virtual nsStyleContext* GetAdditionalStyleContext(PRInt32 aIndex) const = 0;
virtual void SetAdditionalStyleContext(PRInt32 aIndex,
nsStyleContext* aStyleContext) = 0;
// returns GetStyleBorder()->mBoxShadow unless this frame is using
// -moz-appearance and is not chrome
nsCSSShadowArray* GetEffectiveBoxShadows();
/**
* Accessor functions for geometric parent
*/
nsIFrame* GetParent() const { return mParent; }
NS_IMETHOD SetParent(const nsIFrame* aParent) { mParent = (nsIFrame*)aParent; return NS_OK; }
/**
* Bounding rect of the frame. The values are in app units, and the origin is
* relative to the upper-left of the geometric parent. The size includes the
* content area, borders, and padding.
*
* Note: moving or sizing the frame does not affect the view's size or
* position.
*/
nsRect GetRect() const { return mRect; }
nsPoint GetPosition() const { return nsPoint(mRect.x, mRect.y); }
nsSize GetSize() const { return nsSize(mRect.width, mRect.height); }
/**
* When we change the size of the frame's border-box rect, we may need to
* reset the overflow rect if it was previously stored as deltas.
* (If it is currently a "large" overflow and could be re-packed as deltas,
* we don't bother as the cost of the allocation has already been paid.)
*/
void SetRect(const nsRect& aRect) {
if (HasOverflowRect() && mOverflow.mType != NS_FRAME_OVERFLOW_LARGE) {
nsRect r = GetOverflowRect();
mRect = aRect;
SetOverflowRect(r);
} else {
mRect = aRect;
}
}
void SetSize(const nsSize& aSize) {
if (HasOverflowRect() && mOverflow.mType != NS_FRAME_OVERFLOW_LARGE) {
nsRect r = GetOverflowRect();
mRect.SizeTo(aSize);
SetOverflowRect(r);
} else {
mRect.SizeTo(aSize);
}
}
void SetPosition(const nsPoint& aPt) { mRect.MoveTo(aPt); }
/**
* Return frame's computed offset due to relative positioning
*/
nsPoint GetRelativeOffset(const nsStyleDisplay* aDisplay = nsnull) const;
virtual nsPoint GetPositionOfChildIgnoringScrolling(nsIFrame* aChild)
{ return aChild->GetPosition(); }
nsPoint GetPositionIgnoringScrolling() {
return mParent ? mParent->GetPositionOfChildIgnoringScrolling(this)
: GetPosition();
}
/**
* Return the distance between the border edge of the frame and the
* margin edge of the frame. Can only be called after Reflow for the
* frame has at least *started*.
*
* This doesn't include any margin collapsing that may have occurred.
*
* It also treats 'auto' margins as zero, and treats any margins that
* should have been turned into 'auto' because of overconstraint as
* having their original values.
*/
virtual nsMargin GetUsedMargin() const;
/**
* Return the distance between the border edge of the frame (which is
* its rect) and the padding edge of the frame. Can only be called
* after Reflow for the frame has at least *started*.
*
* Note that this differs from GetStyleBorder()->GetBorder() in that
* this describes region of the frame's box, and
* GetStyleBorder()->GetBorder() describes a border. They differ only
* for tables, particularly border-collapse tables.
*/
virtual nsMargin GetUsedBorder() const;
/**
* Return the distance between the padding edge of the frame and the
* content edge of the frame. Can only be called after Reflow for the
* frame has at least *started*.
*/
virtual nsMargin GetUsedPadding() const;
nsMargin GetUsedBorderAndPadding() const {
return GetUsedBorder() + GetUsedPadding();
}
/**
* Apply the result of GetSkipSides() on this frame to an nsMargin by
* setting to zero any sides that are skipped.
*/
void ApplySkipSides(nsMargin& aMargin) const;
/**
* Like the frame's rect (see |GetRect|), which is the border rect,
* other rectangles of the frame, in app units, relative to the parent.
*
* Note that GetMarginRect is not meaningful for blocks (anything with
* 'display:block', whether block frame or not) because of both the
* collapsing and 'auto' issues with GetUsedMargin (on which it
* depends).
*/
nsRect GetMarginRect() const;
nsRect GetPaddingRect() const;
nsRect GetContentRect() const;
/**
* Get the position of the frame's baseline, relative to the top of
* the frame (its top border edge). Only valid when Reflow is not
* needed and when the frame returned nsHTMLReflowMetrics::
* ASK_FOR_ASCENT as ascent in its reflow metrics.
*/
virtual nscoord GetBaseline() const = 0;
/**
* Used to iterate the list of additional child list names. Returns the atom
* name for the additional child list at the specified 0-based index, or a
* NULL pointer if there are no more named child lists.
*
* Note that the list is only the additional named child lists and does not
* include the unnamed principal child list.
*/
virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const = 0;
/**
* Get the first child frame from the specified child list.
*
* @param aListName the name of the child list. A NULL pointer for the atom
* name means the unnamed principal child list
* @return the child frame, or NULL if there is no such child
* @see #GetAdditionalListName()
*/
virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const = 0;
/**
* Child frames are linked together in a singly-linked list
*/
nsIFrame* GetNextSibling() const { return mNextSibling; }
void SetNextSibling(nsIFrame* aNextSibling) {
NS_ASSERTION(this != aNextSibling, "Creating a circular frame list, this is very bad.");
mNextSibling = aNextSibling;
}
/**
* Builds the display lists for the content represented by this frame
* and its descendants. The background+borders of this element must
* be added first, before any other content.
*
* This should only be called by methods in nsFrame. Instead of calling this
* directly, call either BuildDisplayListForStackingContext or
* BuildDisplayListForChild.
*
* See nsDisplayList.h for more information about display lists.
*
* @param aDirtyRect content outside this rectangle can be ignored; the
* rectangle is in frame coordinates
*/
NS_IMETHOD BuildDisplayList(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists) { return NS_OK; }
/**
* Displays the caret onto the given display list builder. The caret is
* painted on top of the rest of the display list items.
*
* @param aDirtyRect is the dirty rectangle that we're repainting.
*/
nsresult DisplayCaret(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists);
PRBool IsThemed(nsTransparencyMode* aTransparencyMode = nsnull) {
return IsThemed(GetStyleDisplay(), aTransparencyMode);
}
PRBool IsThemed(const nsStyleDisplay* aDisp,
nsTransparencyMode* aTransparencyMode = nsnull) {
if (!aDisp->mAppearance)
return PR_FALSE;
nsPresContext* pc = PresContext();
nsITheme *theme = pc->GetTheme();
if(!theme || !theme->ThemeSupportsWidget(pc, this, aDisp->mAppearance))
return PR_FALSE;
if (aTransparencyMode) {
*aTransparencyMode = theme->GetWidgetTransparency(aDisp->mAppearance);
}
return PR_TRUE;
}
/**
* Builds a display list for the content represented by this frame,
* treating this frame as the root of a stacking context.
* @param aDirtyRect content outside this rectangle can be ignored; the
* rectangle is in frame coordinates
*/
nsresult BuildDisplayListForStackingContext(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
nsDisplayList* aList);
/**
* Clips the display items of aFromSet, putting the results in aToSet.
* Only items corresponding to frames which are descendants of this frame
* are clipped. In other words, descendant elements whose CSS boxes do not
* have this frame as a container are not clipped. Also,
* border/background/outline items for this frame are not clipped,
* unless aClipBorderBackground is set to PR_TRUE. (We need this because
* a scrollframe must overflow-clip its scrolled child's background/borders.)
*/
nsresult OverflowClip(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aFromSet,
const nsDisplayListSet& aToSet,
const nsRect& aClipRect,
PRBool aClipBorderBackground = PR_FALSE,
PRBool aClipAll = PR_FALSE);
/**
* Clips the display items of aFromSet, putting the results in aToSet.
* All items are clipped.
*/
nsresult Clip(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aFromSet,
const nsDisplayListSet& aToSet,
const nsRect& aClipRect);
enum {
DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT = 0x01,
DISPLAY_CHILD_FORCE_STACKING_CONTEXT = 0x02,
DISPLAY_CHILD_INLINE = 0x04
};
/**
* Adjusts aDirtyRect for the child's offset, checks that the dirty rect
* actually intersects the child (or its descendants), calls BuildDisplayList
* on the child if necessary, and puts things in the right lists if the child
* is positioned.
*
* @param aFlags combination of DISPLAY_CHILD_FORCE_PSEUDO_STACKING_CONTEXT,
* DISPLAY_CHILD_FORCE_STACKING_CONTEXT and DISPLAY_CHILD_INLINE
*/
nsresult BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
nsIFrame* aChild,
const nsRect& aDirtyRect,
const nsDisplayListSet& aLists,
PRUint32 aFlags = 0);
/**
* Does this frame type always need a view?
*/
virtual PRBool NeedsView() { return PR_FALSE; }
/**
* Returns whether this frame has a transform matrix applied to it. This is true
* if we have the -moz-transform property or if we're an SVGForeignObjectFrame.
*/
virtual PRBool IsTransformed() const;
/**
* This frame needs a view with a widget (e.g. because it's fixed
* positioned), so we call this to create the widget. If widgets for
* this frame type need to be of a certain type or require special
* initialization, that can be done here.
*/
virtual nsresult CreateWidgetForView(nsIView* aView);
/**
* Event handling of GUI events.
*
* @param aEvent event structure describing the type of event and rge widget
* where the event originated
* The |point| member of this is in the coordinate system of the
* view returned by GetOffsetFromView.
* @param aEventStatus a return value indicating whether the event was handled
* and whether default processing should be done
*
* XXX From a frame's perspective it's unclear what the effect of the event status
* is. Does it cause the event to continue propagating through the frame hierarchy
* or is it just returned to the widgets?
*
* @see nsGUIEvent