Fix for bug 63081. We remove carriage returns passed to us by the parser in the copy from the sink buffer to the content model. r=jst
git-svn-id: svn://10.0.0.236/trunk@85317 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -118,4 +118,156 @@ nsLayoutUtils::GetDynamicScriptContext(JSContext *aContext,
|
||||
(void**)aScriptContext);
|
||||
}
|
||||
|
||||
template <class OutputIterator>
|
||||
struct NormalizeNewlinesCharTraits {
|
||||
public:
|
||||
typedef typename OutputIterator::value_type value_type;
|
||||
|
||||
public:
|
||||
NormalizeNewlinesCharTraits(OutputIterator& aIterator) : mIterator(aIterator) { }
|
||||
void writechar(typename OutputIterator::value_type aChar) {
|
||||
*mIterator++ = aChar;
|
||||
}
|
||||
|
||||
private:
|
||||
OutputIterator mIterator;
|
||||
};
|
||||
|
||||
#ifdef HAVE_CPP_PARTIAL_SPECIALIZATION
|
||||
|
||||
template <class CharT>
|
||||
struct NormalizeNewlinesCharTraits<CharT*> {
|
||||
public:
|
||||
typedef CharT value_type;
|
||||
|
||||
public:
|
||||
NormalizeNewlinesCharTraits(CharT* aCharPtr) : mCharPtr(aCharPtr) { }
|
||||
void writechar(CharT aChar) {
|
||||
*mCharPtr++ = aChar;
|
||||
}
|
||||
|
||||
private:
|
||||
CharT* mCharPtr;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
NS_SPECIALIZE_TEMPLATE
|
||||
struct NormalizeNewlinesCharTraits<char*> {
|
||||
public:
|
||||
typedef char value_type;
|
||||
|
||||
public:
|
||||
NormalizeNewlinesCharTraits(char* aCharPtr) : mCharPtr(aCharPtr) { }
|
||||
void writechar(char aChar) {
|
||||
*mCharPtr++ = aChar;
|
||||
}
|
||||
|
||||
private:
|
||||
char* mCharPtr;
|
||||
};
|
||||
|
||||
NS_SPECIALIZE_TEMPLATE
|
||||
struct NormalizeNewlinesCharTraits<PRUnichar*> {
|
||||
public:
|
||||
typedef PRUnichar value_type;
|
||||
|
||||
public:
|
||||
NormalizeNewlinesCharTraits(PRUnichar* aCharPtr) : mCharPtr(aCharPtr) { }
|
||||
void writechar(PRUnichar aChar) {
|
||||
*mCharPtr++ = aChar;
|
||||
}
|
||||
|
||||
private:
|
||||
PRUnichar* mCharPtr;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <class OutputIterator>
|
||||
class CopyNormalizeNewlines
|
||||
{
|
||||
public:
|
||||
typedef typename OutputIterator::value_type value_type;
|
||||
|
||||
public:
|
||||
CopyNormalizeNewlines(OutputIterator* aDestination) :
|
||||
mLastCharCR(PR_FALSE),
|
||||
mDestination(aDestination),
|
||||
mWritten(0)
|
||||
{ }
|
||||
|
||||
PRUint32 GetCharsWritten() {
|
||||
return mWritten;
|
||||
}
|
||||
|
||||
PRUint32 write(const typename OutputIterator::value_type* aSource, PRUint32 aSourceLength) {
|
||||
// If the last source buffer ended with a CR...
|
||||
if (mLastCharCR) {
|
||||
// ..and if the next one is a LF, then skip it since
|
||||
// we've already written out a newline
|
||||
if (aSourceLength && (*aSource == value_type('\n'))) {
|
||||
aSource++;
|
||||
}
|
||||
mLastCharCR = PR_FALSE;
|
||||
}
|
||||
|
||||
const typename OutputIterator::value_type* done_writing = aSource + aSourceLength;
|
||||
PRUint32 num_written = 0;
|
||||
while ( aSource < done_writing ) {
|
||||
if (*aSource == value_type('\r')) {
|
||||
mDestination->writechar('\n');
|
||||
aSource++;
|
||||
// If we've reached the end of the buffer, record
|
||||
// that we wrote out a CR
|
||||
if (aSource == done_writing) {
|
||||
mLastCharCR = PR_TRUE;
|
||||
}
|
||||
// If the next character is a LF, skip it
|
||||
else if (*aSource == value_type('\n')) {
|
||||
aSource++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mDestination->writechar(*aSource++);
|
||||
}
|
||||
num_written++;
|
||||
}
|
||||
|
||||
mWritten += num_written;
|
||||
return aSourceLength;
|
||||
}
|
||||
|
||||
private:
|
||||
PRBool mLastCharCR;
|
||||
OutputIterator* mDestination;
|
||||
PRUint32 mWritten;
|
||||
};
|
||||
|
||||
// static
|
||||
PRUint32
|
||||
nsLayoutUtils::CopyNewlineNormalizedUnicodeTo(const nsAReadableString& aSource, PRUint32 aSrcOffset, PRUnichar* aDest, PRUint32 aLength)
|
||||
{
|
||||
typedef NormalizeNewlinesCharTraits<PRUnichar*> sink_traits;
|
||||
|
||||
sink_traits dest_traits(aDest);
|
||||
CopyNormalizeNewlines<sink_traits> normalizer(&dest_traits);
|
||||
nsReadingIterator<PRUnichar> fromBegin, fromEnd;
|
||||
copy_string(aSource.BeginReading(fromBegin).advance( PRInt32(aSrcOffset) ), aSource.BeginReading(fromEnd).advance( PRInt32(aSrcOffset+aLength) ), normalizer);
|
||||
return normalizer.GetCharsWritten();
|
||||
}
|
||||
|
||||
// static
|
||||
PRUint32
|
||||
nsLayoutUtils::CopyNewlineNormalizedUnicodeTo(nsReadingIterator<PRUnichar>& aSrcStart, const nsReadingIterator<PRUnichar>& aSrcEnd, nsAWritableString& aDest)
|
||||
{
|
||||
typedef nsWritingIterator<PRUnichar> WritingIterator;
|
||||
typedef NormalizeNewlinesCharTraits<WritingIterator> sink_traits;
|
||||
|
||||
WritingIterator iter;
|
||||
aDest.BeginWriting(iter);
|
||||
sink_traits dest_traits(iter);
|
||||
CopyNormalizeNewlines<sink_traits> normalizer(&dest_traits);
|
||||
copy_string(aSrcStart, aSrcEnd, normalizer);
|
||||
return normalizer.GetCharsWritten();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user