|
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 /* |
|
7 * a list of the recomputation that needs to be done in response to a |
|
8 * style change |
|
9 */ |
|
10 |
|
11 #include "nsStyleChangeList.h" |
|
12 #include "nsIContent.h" |
|
13 |
|
14 static const uint32_t kGrowArrayBy = 10; |
|
15 |
|
16 nsStyleChangeList::nsStyleChangeList() |
|
17 : mArray(mBuffer), |
|
18 mArraySize(kStyleChangeBufferSize), |
|
19 mCount(0) |
|
20 { |
|
21 MOZ_COUNT_CTOR(nsStyleChangeList); |
|
22 } |
|
23 |
|
24 nsStyleChangeList::~nsStyleChangeList() |
|
25 { |
|
26 MOZ_COUNT_DTOR(nsStyleChangeList); |
|
27 Clear(); |
|
28 } |
|
29 |
|
30 nsresult |
|
31 nsStyleChangeList::ChangeAt(int32_t aIndex, nsIFrame*& aFrame, nsIContent*& aContent, |
|
32 nsChangeHint& aHint) const |
|
33 { |
|
34 if ((0 <= aIndex) && (aIndex < mCount)) { |
|
35 aFrame = mArray[aIndex].mFrame; |
|
36 aContent = mArray[aIndex].mContent; |
|
37 aHint = mArray[aIndex].mHint; |
|
38 return NS_OK; |
|
39 } |
|
40 return NS_ERROR_ILLEGAL_VALUE; |
|
41 } |
|
42 |
|
43 nsresult |
|
44 nsStyleChangeList::ChangeAt(int32_t aIndex, const nsStyleChangeData** aChangeData) const |
|
45 { |
|
46 if ((0 <= aIndex) && (aIndex < mCount)) { |
|
47 *aChangeData = &mArray[aIndex]; |
|
48 return NS_OK; |
|
49 } |
|
50 return NS_ERROR_ILLEGAL_VALUE; |
|
51 } |
|
52 |
|
53 nsresult |
|
54 nsStyleChangeList::AppendChange(nsIFrame* aFrame, nsIContent* aContent, nsChangeHint aHint) |
|
55 { |
|
56 NS_ASSERTION(aFrame || (aHint & nsChangeHint_ReconstructFrame), |
|
57 "must have frame"); |
|
58 NS_ASSERTION(aContent || !(aHint & nsChangeHint_ReconstructFrame), |
|
59 "must have content"); |
|
60 // XXXbz we should make this take Element instead of nsIContent |
|
61 NS_ASSERTION(!aContent || aContent->IsElement(), |
|
62 "Shouldn't be trying to restyle non-elements directly"); |
|
63 NS_ASSERTION(!(aHint & nsChangeHint_AllReflowHints) || |
|
64 (aHint & nsChangeHint_NeedReflow), |
|
65 "Reflow hint bits set without actually asking for a reflow"); |
|
66 |
|
67 if ((0 < mCount) && (aHint & nsChangeHint_ReconstructFrame)) { // filter out all other changes for same content |
|
68 if (aContent) { |
|
69 for (int32_t index = mCount - 1; index >= 0; --index) { |
|
70 if (aContent == mArray[index].mContent) { // remove this change |
|
71 aContent->Release(); |
|
72 mCount--; |
|
73 if (index < mCount) { // move later changes down |
|
74 ::memmove(&mArray[index], &mArray[index + 1], |
|
75 (mCount - index) * sizeof(nsStyleChangeData)); |
|
76 } |
|
77 } |
|
78 } |
|
79 } |
|
80 } |
|
81 |
|
82 int32_t last = mCount - 1; |
|
83 if ((0 < mCount) && aFrame && (aFrame == mArray[last].mFrame)) { // same as last frame |
|
84 NS_UpdateHint(mArray[last].mHint, aHint); |
|
85 } |
|
86 else { |
|
87 if (mCount == mArraySize) { |
|
88 int32_t newSize = mArraySize + kGrowArrayBy; |
|
89 nsStyleChangeData* newArray = new nsStyleChangeData[newSize]; |
|
90 if (newArray) { |
|
91 memcpy(newArray, mArray, mCount * sizeof(nsStyleChangeData)); |
|
92 if (mArray != mBuffer) { |
|
93 delete [] mArray; |
|
94 } |
|
95 mArray = newArray; |
|
96 mArraySize = newSize; |
|
97 } |
|
98 else { |
|
99 return NS_ERROR_OUT_OF_MEMORY; |
|
100 } |
|
101 } |
|
102 mArray[mCount].mFrame = aFrame; |
|
103 mArray[mCount].mContent = aContent; |
|
104 if (aContent) { |
|
105 aContent->AddRef(); |
|
106 } |
|
107 mArray[mCount].mHint = aHint; |
|
108 mCount++; |
|
109 } |
|
110 return NS_OK; |
|
111 } |
|
112 |
|
113 void |
|
114 nsStyleChangeList::Clear() |
|
115 { |
|
116 for (int32_t index = mCount - 1; index >= 0; --index) { |
|
117 nsIContent* content = mArray[index].mContent; |
|
118 if (content) { |
|
119 content->Release(); |
|
120 } |
|
121 } |
|
122 if (mArray != mBuffer) { |
|
123 delete [] mArray; |
|
124 mArray = mBuffer; |
|
125 mArraySize = kStyleChangeBufferSize; |
|
126 } |
|
127 mCount = 0; |
|
128 } |
|
129 |