1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/base/nsStyleChangeList.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,129 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* 1.10 + * a list of the recomputation that needs to be done in response to a 1.11 + * style change 1.12 + */ 1.13 + 1.14 +#include "nsStyleChangeList.h" 1.15 +#include "nsIContent.h" 1.16 + 1.17 +static const uint32_t kGrowArrayBy = 10; 1.18 + 1.19 +nsStyleChangeList::nsStyleChangeList() 1.20 + : mArray(mBuffer), 1.21 + mArraySize(kStyleChangeBufferSize), 1.22 + mCount(0) 1.23 +{ 1.24 + MOZ_COUNT_CTOR(nsStyleChangeList); 1.25 +} 1.26 + 1.27 +nsStyleChangeList::~nsStyleChangeList() 1.28 +{ 1.29 + MOZ_COUNT_DTOR(nsStyleChangeList); 1.30 + Clear(); 1.31 +} 1.32 + 1.33 +nsresult 1.34 +nsStyleChangeList::ChangeAt(int32_t aIndex, nsIFrame*& aFrame, nsIContent*& aContent, 1.35 + nsChangeHint& aHint) const 1.36 +{ 1.37 + if ((0 <= aIndex) && (aIndex < mCount)) { 1.38 + aFrame = mArray[aIndex].mFrame; 1.39 + aContent = mArray[aIndex].mContent; 1.40 + aHint = mArray[aIndex].mHint; 1.41 + return NS_OK; 1.42 + } 1.43 + return NS_ERROR_ILLEGAL_VALUE; 1.44 +} 1.45 + 1.46 +nsresult 1.47 +nsStyleChangeList::ChangeAt(int32_t aIndex, const nsStyleChangeData** aChangeData) const 1.48 +{ 1.49 + if ((0 <= aIndex) && (aIndex < mCount)) { 1.50 + *aChangeData = &mArray[aIndex]; 1.51 + return NS_OK; 1.52 + } 1.53 + return NS_ERROR_ILLEGAL_VALUE; 1.54 +} 1.55 + 1.56 +nsresult 1.57 +nsStyleChangeList::AppendChange(nsIFrame* aFrame, nsIContent* aContent, nsChangeHint aHint) 1.58 +{ 1.59 + NS_ASSERTION(aFrame || (aHint & nsChangeHint_ReconstructFrame), 1.60 + "must have frame"); 1.61 + NS_ASSERTION(aContent || !(aHint & nsChangeHint_ReconstructFrame), 1.62 + "must have content"); 1.63 + // XXXbz we should make this take Element instead of nsIContent 1.64 + NS_ASSERTION(!aContent || aContent->IsElement(), 1.65 + "Shouldn't be trying to restyle non-elements directly"); 1.66 + NS_ASSERTION(!(aHint & nsChangeHint_AllReflowHints) || 1.67 + (aHint & nsChangeHint_NeedReflow), 1.68 + "Reflow hint bits set without actually asking for a reflow"); 1.69 + 1.70 + if ((0 < mCount) && (aHint & nsChangeHint_ReconstructFrame)) { // filter out all other changes for same content 1.71 + if (aContent) { 1.72 + for (int32_t index = mCount - 1; index >= 0; --index) { 1.73 + if (aContent == mArray[index].mContent) { // remove this change 1.74 + aContent->Release(); 1.75 + mCount--; 1.76 + if (index < mCount) { // move later changes down 1.77 + ::memmove(&mArray[index], &mArray[index + 1], 1.78 + (mCount - index) * sizeof(nsStyleChangeData)); 1.79 + } 1.80 + } 1.81 + } 1.82 + } 1.83 + } 1.84 + 1.85 + int32_t last = mCount - 1; 1.86 + if ((0 < mCount) && aFrame && (aFrame == mArray[last].mFrame)) { // same as last frame 1.87 + NS_UpdateHint(mArray[last].mHint, aHint); 1.88 + } 1.89 + else { 1.90 + if (mCount == mArraySize) { 1.91 + int32_t newSize = mArraySize + kGrowArrayBy; 1.92 + nsStyleChangeData* newArray = new nsStyleChangeData[newSize]; 1.93 + if (newArray) { 1.94 + memcpy(newArray, mArray, mCount * sizeof(nsStyleChangeData)); 1.95 + if (mArray != mBuffer) { 1.96 + delete [] mArray; 1.97 + } 1.98 + mArray = newArray; 1.99 + mArraySize = newSize; 1.100 + } 1.101 + else { 1.102 + return NS_ERROR_OUT_OF_MEMORY; 1.103 + } 1.104 + } 1.105 + mArray[mCount].mFrame = aFrame; 1.106 + mArray[mCount].mContent = aContent; 1.107 + if (aContent) { 1.108 + aContent->AddRef(); 1.109 + } 1.110 + mArray[mCount].mHint = aHint; 1.111 + mCount++; 1.112 + } 1.113 + return NS_OK; 1.114 +} 1.115 + 1.116 +void 1.117 +nsStyleChangeList::Clear() 1.118 +{ 1.119 + for (int32_t index = mCount - 1; index >= 0; --index) { 1.120 + nsIContent* content = mArray[index].mContent; 1.121 + if (content) { 1.122 + content->Release(); 1.123 + } 1.124 + } 1.125 + if (mArray != mBuffer) { 1.126 + delete [] mArray; 1.127 + mArray = mBuffer; 1.128 + mArraySize = kStyleChangeBufferSize; 1.129 + } 1.130 + mCount = 0; 1.131 +} 1.132 +